A. Jzzhu and Chocolate
题意 : 给定一个n*m 的巧克力 , 切 K 刀 , 问切完后的巧克力块中面积最小的巧克力块面积最大是多少 ?
思路 : 假设对于长度为n的边切 i 刀 , 那么结果就 ( n / ( i + 1 ) ) * ( m / ( k - i + 1 ) ) .。打个表感觉了下 , 发现两端一定是最大的 , 那么就解决了 , 两端取最大值就好
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
__int64 n , m , k ;
int main(){
while( scanf("%I64d%I64d%I64d" , &n , &m , &k )!= EOF ) {
if( n - 1 + m - 1 < k ) {
puts( "-1" ) ;
continue ;
}else{
__int64 Min = max( (__int64)0 , k - m + 1 ) ;
__int64 Max = min( n - 1 , k ) ;
__int64 ans1 = ( n / ( Min + 1 ) )* ( m / ( k - Min + 1 ) ) ;
__int64 ans2 = ( n / ( Max + 1 ) )* ( m / ( k - Max + 1 ) ) ;
printf( "%I64d\n" , max( ans1 , ans2 ) ) ;
}
}
return 0 ;
}
B. Jzzhu and Cities
题意 : n 个点 , m 条普通的双向边 , k条车轨 。 我们要拆掉最多的车轨 , 但是要保持每个点的最短路径不变 。
思路 : spfa 求最短路 , 迭代的时候特判下距离相等的时候 , 优先选择非车轨的边 ,是否选择了车轨的边用一个bool数组保存 。不过最后TLE 45 了,据说出题人特意卡的没有优化过的spfa
,原来是hack的数据 。。。后来加slf优化就A了。
SPFA的优化可以看这里 : http://www.cnblogs.com/pony1993/archive/2012/09/07/2675654.html
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 100005
#define MAXM 700005
typedef __int64 LL ;
int n , m , k ;
struct Graph {
struct Edge {
int to , nex ; LL val ;
bool isK ;
Edge() {}
Edge ( int _to , LL _val , int _nex , bool _isK ) {
to = _to , val = _val , nex = _nex ; isK = _isK ;
}
} edge[MAXM] ;
int head[MAXN] ;
int Index ;
void init() {
memset ( head , -1 , sizeof ( head ) ) ;
Index = 0 ;
}
void add ( int from , int to , LL val , bool isK ) {
edge[Index] = Edge ( to , val , head[from] , isK ) ;
head[from] = Index ++ ;
}
} gra;
LL dis[MAXN];
bool inq[MAXN];
bool preisK[MAXN] ;
deque<int>Q;
void init(){
memset( dis , 0x3f , sizeof(dis) ) ;
memset( inq , false , sizeof(inq) ) ;
memset( preisK , false , sizeof(preisK) ) ;
while(!Q.empty()) Q.pop_front() ;
}
void spfa ( int start ) {
dis[start] = 0;
Q.push_back ( start );
inq[start] = true;
while ( !Q.empty() ) {
int tmp = Q.front();
Q.pop_front();
inq[tmp] = false;
for ( int e = gra.head[tmp]; ~e; e = gra.edge[e].nex ) {
int to = gra.edge[e].to;
LL val = gra.edge[e].val;
if ( dis[to] > dis[tmp] + val ) {
dis[to] = dis[tmp] + val;
preisK[to] = gra.edge[e].isK ;
if ( !inq[to] ) {
inq[to] = true;
if( Q.empty() || dis[to] > dis[Q.front()] )
Q.push_back ( to );
else
Q.push_front( to ) ;
}
} else if( dis[to] == dis[tmp] + val && preisK[to] && gra.edge[e].isK == false ) {
preisK[to] = false ;
}
}
}
}
int main(){
while( scanf( "%d%d%d" , &n , &m , &k ) != EOF ) {
gra.init() ;
for( int i = 1 ; i <= m ; i ++ ) {
int from , to ;
LL val ;
scanf( "%d%d%I64d" , &from, &to , &val ) ;
gra.add( from , to , val , false ) ;
gra.add( to , from , val , false ) ;
}
for( int i = 1 ; i <= k ; i ++ ) {
int s ; LL val ;
scanf( "%d%I64d" , &s , &val ) ;
gra.add( 1 , s , val , true ) ;
}
init() ;
spfa( 1 ) ;
int cnt = 0 ;
for( int i = 2 ; i <= n; i ++ ) {
if( preisK[i] ) {
cnt ++ ;
}
}
printf( "%d\n" , k - cnt ) ;
}
return 0 ;
}