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;
}
浙公网安备 33010602011771号