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;
}
View Code

 

posted @ 2019-09-30 21:16  starve_to_death  阅读(137)  评论(0编辑  收藏  举报