Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:谁用Dinic过的这题。。?我头回遇到Dinic也超时的In Reply To:谁用Dinic过的这题。。?我头回遇到Dinic也超时的 Posted by:heimengnan at 2010-02-27 15:54:23 #include<iostream> #include<queue> #include<cstring> #include<cstdio> #include<climits> #define MAXE 65100*2 #define MAXP 5100 #define Max(a,b) a>b?a:b #define Min(a,b) a<b?a:b using namespace std; struct Edge { long long int s,t,next; long long f; } edge[MAXE]; long long int head[MAXP]; long long int cur[MAXP]; long long int pre[MAXP]; long long int stack[MAXE]; long long int dep[MAXP]; long long int ent; long long int n,m,s,t,cot; void add(long long int start,long long int last,long long int f) { edge[ent].s=start; edge[ent].t=last; edge[ent].f=f; edge[ent].next=head[start]; head[start]=ent++; edge[ent].s=last; edge[ent].t=start; edge[ent].f=0; edge[ent].next=head[last]; head[last]=ent++; } bool bfs(long long int S,long long int T) { memset(pre,-1,sizeof(pre)); pre[S]=0; queue<long long int>q; q.push(S); while(!q.empty()) { long long int temp=q.front(); q.pop(); for(long long int i=head[temp]; i!=-1; i=edge[i].next) { long long int temp2=edge[i].t; if(pre[temp2]==-1&&edge[i].f) { pre[temp2]=pre[temp]+1; q.push(temp2); } } } return pre[T]!=-1; } long long int dinic(long long int start,long long int last) { long long int flow=0,now; while(bfs(start,last)) { long long int top=0; memcpy(cur,head,sizeof(head)); long long int u=start; while(1) { if(u==last)//如果找到终点结束对中间路径进行处理并计算出该流 { long long int minn=INT_MAX; for(long long int i=0; i<top; i++) { if(minn>edge[stack[i]].f) { minn=edge[stack[i]].f; now=i; } } flow+=minn; for(long long int i=0; i<top; i++) { edge[stack[i]].f-=minn; edge[stack[i]^1].f+=minn; } top=now; u=edge[stack[top]].s; } for(long long int i=cur[u]; i!=-1; cur[u]=i=edge[i].next) //找出从u点出发能到的边 if(edge[i].f&&pre[edge[i].t]==pre[u]+1) break; if(cur[u]==-1)//如果从该点未找到可行边,将该点标记并回溯 { if(top==0)break; pre[u]=-1; u=edge[stack[--top]].s; } else//如果找到了继续运行 { stack[top++]=cur[u]; u=edge[cur[u]].t; } } } return flow; } void dfs(long long int u) { cot++; dep[u]=1; for(long long int i=head[u];i!=-1;i=edge[i].next) { long long int v=edge[i].t; if(!dep[v]&&edge[i].f>0) { dfs(v); } } } int main() { while(~scanf("%lld%lld",&n,&m)) { s=0; t=n+1; ent=0; long long int cost,u,v; long long int ans=0; memset(head,-1,sizeof(head)); for(int i=1; i<=n; i++) { scanf("%lld",&cost); if(cost>0) { add(s,i,cost); ans+=cost; } else add(i,t,-cost); } for(int i=1; i<=m; i++) { scanf("%lld%lld",&u,&v); add(u,v,INT_MAX); } memset(dep,0,sizeof(dep)); long long int flow=dinic(s,t); cot=0; dfs(s); printf("%lld ",cot-1); printf("%lld\n",ans-flow); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator