标签:
[困]坑点:无向边,每条边只能走一次,但正向走一次后反向还能走一次,所以每次输入要建四条边。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <queue> using namespace std; int n,m,cnt; int head[50500],vis[50500],pre[50500]; long long dis[50500]; struct edge{ int u,v,w,cap,next; }e[50050<<2]; void Initial() { memset(head,-1,sizeof(head)); } bool SPFA() { memset(pre,-1,sizeof(pre)); for(int i=0;i<=n+2;i++){ dis[i]=1e11; } memset(vis,0,sizeof(vis)); queue <int>que; vis[0]=1; que.push(0); dis[0]=0; while(!que.empty()){ int d=que.front(); que.pop(); vis[d]=0; for(int i=head[d];i!=-1;i=e[i].next){ int v=e[i].v; if(dis[v]>dis[d]+e[i].w && e[i].cap){ dis[v]=dis[d]+e[i].w; pre[v]=i; if(!vis[v]){ vis[v]=1; que.push(v); } } } } if(dis[n+1]<1e11){ return true; } return false; } int MCMF() { int flow=0,mincost=0; while(SPFA()){ long long Minflow=1e11; int d=n+1; for(int i=pre[d];i!=-1;i=pre[e[i].u]){ Minflow=min(Minflow,(long long)e[i].cap); } flow+=Minflow; for(int i=pre[d];i!=-1;i=pre[e[i].u]){ e[i].cap-=Minflow; e[i^1].cap+=Minflow; } mincost+=dis[d]; } return mincost; } void add(int u,int v, int cap,int w) { e[cnt].u=u; e[cnt].v=v; e[cnt].w=w; e[cnt].cap=cap; e[cnt].next=head[e[cnt].u]; head[u]=cnt++; e[cnt].v=u; e[cnt].u=v; e[cnt].w=-1*w; e[cnt].cap=0; e[cnt].next=head[e[cnt].u]; head[v]=cnt++; } int main() { while(~scanf("%d%d",&n,&m)){ cnt=0; Initial(); for(int i=0;i<m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,1,w); add(v,u,1,w); } add(0,1,2,0); add(n,n+1,2,0); int ans=MCMF(); printf("%d\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Scale-the-heights/p/4388627.html