POJ 3068 "Shortest" pair of paths
题意:选俩条除起点终点(1为起点,n为终点),所经过互不相交的路径,并要求最小cost
分析:很明显的最小费用最大流问题,最大流为路径数时2,
经验:要熟悉这种题型:“互不相交的路径”可以望网络流方向思考
#include<bits/stdc++.h> using namespace std; const int M=100; const int N=1e4+10; const int inf=0x3f3f3f3f; int mincost,tot,s,t,head[M],cur[M],dis[M],vis[M]; struct node{ int v,w,cost,nextt; }e[N<<1]; void addedge(int u,int v,int w,int cost){ e[tot].v=v; e[tot].w=w; e[tot].cost=cost; e[tot].nextt=head[u]; head[u]=tot++; e[tot].v=u; e[tot].w=0; e[tot].cost=-cost; e[tot].nextt=head[v]; head[v]=tot++; } bool bfs(){ for(int i=0;i<=t;i++) dis[i]=inf,vis[i]=0; queue<int>que; que.push(s); dis[s]=0; while(!que.empty()){ int u=que.front(); que.pop(); vis[u]=0; for(int i=head[u];~i;i=e[i].nextt){ int v=e[i].v; if(e[i].w>0&&dis[v]>dis[u]+e[i].cost){ dis[v]=dis[u]+e[i].cost; if(!vis[v]){ que.push(v); vis[v]=1; } } } } return dis[t]!=inf; } int dfs(int u,int fl){ if(u==t) return fl; vis[u]=1; int ans=0; for(int i=cur[u];~i;i=e[i].nextt){ int v=e[i].v; if(e[i].w&&!vis[v]&&dis[v]==dis[u]+e[i].cost){ cur[u]=i; int x=dfs(v,min(e[i].w,fl-ans)); e[i].w-=x; e[i^1].w+=x; ans+=x; mincost+=x*e[i].cost; if(ans==fl) break; } } vis[u]=0; return ans; } int MFMC(){ int ans=0; while(bfs()){ for(int i=0;i<=t;i++) cur[i]=head[i]; ans+=dfs(s,inf); } return ans; } int main(){ int n,m,countt=1; while(~scanf("%d%d",&n,&m)){ if(n+m==0) break; for(int i=0;i<=n+1;i++) head[i]=-1; tot=mincost=0; for(int i=1,u,v,w;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); u++,v++; addedge(u,v,1,w); } s=0,t=n+1; addedge(s,1,2,0); addedge(n,t,2,0); printf("Instance #%d: ",countt++); if(MFMC()==2) printf("%d\n",mincost); else puts("Not possible"); } return 0; }