http://acm.hdu.edu.cn/showproblem.php?pid=4280
最大流 应该是考 ISAP 的题 但是Dinic 也能过 但是要看人品
自己只会写Dinic 所以就把Dinic 很多小的地方不断优化 终于6000+ms过了
但这并不是目的 有时间还是要好好看看ISAP的
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #define LL long long //外挂开栈 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int N=100003; const int INF=0x5fffffff; int head[N]; struct node { int j,next; int s; }side[N*2]; int I; int L[N]; int st,nd; int qt[N];//手工队列 int bfs() { memset(L,-1,sizeof(L)); L[st]=0; int K=0,J=0; qt[J]=st;++J; while(K<J) { int x=qt[K];++K; for(int t=head[x];t!=-1;t=side[t].next) { int l=side[t].j; if(side[t].s>0&&L[l]==-1) { L[l]=L[x]+1; qt[J]=l;++J; } } } return L[nd]; } int dfs(int x,int sum) { if(x==nd) return sum; int temp=sum; for(int t=head[x];t!=-1;t=side[t].next) { if(L[side[t].j]==L[x]+1&&side[t].s>0) { int w; if(temp<side[t].s) w=dfs(side[t].j,temp); else w=dfs(side[t].j,side[t].s); side[t].s-=w; temp-=w; if(temp==0) break; } } if(sum==temp)//一旦某点无法更新最大流 则将标号改成-2 不再用 L[x]=-2; return (sum-temp); } int main() { //freopen("data.txt","r",stdin); int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d %d",&n,&m); int stK=INF,ndK=-INF; for(int i=1;i<=n;++i) { int x,y; scanf("%d %d",&x,&y); if(x<stK) {stK=x;st=i;} if(x>ndK) {ndK=x;nd=i;} } memset(head,-1,sizeof(head)); I=0; while(m--) { int i,j,s; scanf("%d %d %d",&i,&j,&s); //将建树写在这里 不用函数 事实证明在这个题里可以省很多时间 side[I].j=j; side[I].s=s; side[I].next=head[i]; head[i]=I++; side[I].j=i; side[I].s=s; side[I].next=head[j]; head[j]=I++; } int ans=0; while(bfs()!=-1) { int k; while(k=dfs(st,INF)) ans+=k; } printf("%d\n",ans); } return 0; }