思路構圖還是十分的好想的... 比較的有經驗了。對這題,沒啥難度了。
題目大意:
FJ有很多田地,一些田地有雨棚,雨棚有容納牛的容量,現在給你田中的牛和闐裡的雨棚的容納量,還有田間路徑走完花費的時間。
要求出使得所有牛都躲進雨棚裡的最小時間。
構圖還是很簡單的:
將牛棚拆點為in和out點。
源點到in容量為牛棚中牛的數量,out到匯點為牛棚的容量。in--out為無窮大。
二分枚舉時間,若兩牛棚的時間小於枚舉時間,則in1--out2有邊容量為無窮大。
soso....
這麼一寫就過了....
這題噁心的地方就是時間枚舉要long long 而坑爹的我找不到__int64 的最大值常量了= =
後來才發現有這樣寫的= = long long inf=1ll<<60;
#include<iostream>#include<string>#define MN 444#define INF 0x3FFFFFFF#define FF(i,N) for( int i=0;i<N;i++ )#define CC(a) memset( a,0,sizeof(a) )template<class T> void inline checkmin( T &a,T b ){ if( a>b||a==-1 ) a=b; }using namespace std;const long long oo=1ll<<58;struct edge{ int u,v,len;}E[2222];int F,P,s,t,tot;__int64 map[MN][MN];int maze[MN][MN],cap[MN][MN];bool cmp( edge a,edge b ){ return a.len<b.len; }void setG(){ memset( map,0x3F,sizeof(map) ); CC(maze),CC(cap); s=0;t=2*F+1;tot=0; FF( i,F ){ scanf( "%d%d",&maze[s][i+1],&maze[i+1+F][t] ); maze[i+1][i+1+F]=INF; tot+=maze[s][i+1]; } int u,v,len; FF( i,P ){ scanf( "%d%d%d",&u,&v,&len ); if( map[u][v]>len ) map[u][v]=map[v][u]=len; } for( int i=1;i<=F;i++ ) map[i][i]=0; for( int k=1;k<=F;k++ ) for( int i=1;i<=F;i++ ) for( int j=1;j<=F;j++ ) if( map[i][j]>map[i][k]+map[k][j] ) map[i][j]=map[i][k]+map[k][j];}void initG( __int64 mid ){ for( int i=0;i<=t;i++ ) for( int j=0;j<=t;j++ ) cap[i][j]=maze[i][j]; for( int i=1;i<=F;i++ ) for( int j=1;j<=F;j++ ) if( map[i][j]<=mid ) cap[i][j+F]=INF;}int cur[MN],pre[MN],dis[MN],gap[MN];int sap(){ CC(cur),CC(pre),CC(dis),CC(gap); int u=pre[s]=s,maxflow=0,aug=-1; gap[0]=t+1; while( dis[s]<=t ){loop: for( int v=cur[u];v<=t;v++ ){ if( cap[u][v]&&dis[u]==dis[v]+1 ) { pre[v]=u; cur[u]=v; checkmin( aug,cap[u][v] ); u=v; if( v==t ) { maxflow+=aug; for( u=pre[u];v!=s;v=u,u=pre[u] ) cap[u][v]-=aug,cap[v][u]+=aug; aug=-1; } goto loop; } } int mind=t; for( int v=0;v<=t;v++ ) if( cap[u][v]&&mind>dis[v] ){ mind=dis[v]; cur[u]=v; } if( --gap[dis[u]]==0 )break; gap[dis[u]=mind+1]++; u=pre[u]; } return maxflow;}int main(){ while( scanf("%d%d",&F,&P)!=EOF ) { setG(); __int64 l=1,r=(oo),mid; while( (mid=(l+r)/2)&&l<r ) { initG(mid); if( tot==sap() ) r=mid; else l=mid+1; } if( mid==(oo) ) printf( "-1\n" ); else printf( "%I64d\n",mid ); } return 0;}