http://acm.timus.ru/problem.aspx?space=1&num=1277
拆点建图 dinic 加一点小优化
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<map> #include<vector> #include<stack> #include<set> #include<map> #include<queue> #include<algorithm> #include<cmath> #define LL long long using namespace std; const int INF=0x3f3f3f3f; const int N=205; const int M=100005; int head[N],I; struct node { int j,next; int flow; }edge[M]; int L[N];//距离标号 int st,nd;// void add(int i,int j,int flow)//建图 { edge[I].j=j; edge[I].flow=flow; edge[I].next=head[i]; head[i]=I++; } bool bfs(int x1,int x2)//从汇点向源点搜索并标号 如果搜不到返回 false { //和从源点向汇点搜索并标号相比 在dfs的时候会节省一定的时间 memset(L,-1,sizeof(L)); queue<int>qt; qt.push(x1); L[x1]=0; while(!qt.empty()) { int x=qt.front(); qt.pop(); for(int t=head[x];t!=-1;t=edge[t].next) { int j=edge[t].j; if(edge[t^1].flow>0&&L[j]==-1)//注意这里的边是 edge[t^1].flow 因为我们是反向搜索 { L[j]=L[x]+1; qt.push(j); } } } if(L[x2]==-1) return false; return true; } int dfs(int x,int sum) { if(x==nd) return sum; int tmp=sum; for(int t=head[x];t!=-1;t=edge[t].next) { int j=edge[t].j; if(edge[t].flow>0&&L[x]==L[j]+1) { int w=dfs(j,min(tmp,edge[t].flow)); edge[t].flow-=w; edge[t^1].flow+=w; tmp-=w; if(tmp==0) break; } } return (sum-tmp); } void init(int n,int m,int s,int f) { for(int i=1;i<=n;++i) { int k; cin>>k; if(i==s||i==f) continue; add(i,i+n,k); add(i+n,i,k); } while(m--) { int l,r; cin>>l>>r; if(l==s&&r==f) {add(l,r,INF);add(r,l,0);continue;} if(r==s&&l==f) {add(r,l,INF);add(l,r,0);continue;} if(l==s) {add(l,r,INF);add(r,l,0);} else {add(l+n,r,INF);add(r,l+n,0);} if(r==s) {add(r,l,INF);add(l,r,0);} else {add(r+n,l,INF);add(l,r+n,0);} } } int main() { //freopen("data.in","r",stdin); int K; while(scanf("%d",&K)!=EOF) { memset(head,-1,sizeof(head)); I=0; int n,m,s,f; cin>>n>>m>>s>>f; st=s;//初始化源点和汇点 nd=f; init(n,m,s,f);//建图 int ans=0;//最大流 while(bfs(nd,st))//从汇点向源点bfs { int k; while((k=dfs(st,INF))) {ans+=k;if(ans>K) break;} if(ans>K)//优化在这里 如果ans大于K了以后 就没有必要再搜了 break;//因为答案一定是"NO"了 而且K的上界是10000 所以会很快 } if(ans<=K) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }