uva1349Optimal Bus Route Design

二分图最小权完美匹配。

一个最小费用流就能跑了,记住检查一下,容量是否跑满,如果没有跑满,就说明没有完美匹配。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 500+10;
const int maxm = 50000 + 10;
const int inf = 0x3f3f3f3f;

int g[maxn],v[maxm],f[maxm],c[maxm],nex[maxm],eid;
int id[maxn][2],vid;
int n,ans,S,T;
bool inque[maxn];
int q[maxm],dist[maxn],pre[maxn];

void addedge(int a,int b,int F,int C) {
    v[eid]=b; f[eid]=F; c[eid]=C; nex[eid]=g[a]; g[a]=eid++;
    v[eid]=a; f[eid]=0; c[eid]=-C; nex[eid]=g[b]; g[b]=eid++;    
}

bool build() {
    if(scanf("%d",&n)==1&&n) {
        memset(g,-1,sizeof(g)); eid=0; vid=0;
        S=++vid; T=++vid;
        for(int i=1;i<=n;i++) {
            id[i][0]=++vid;
            id[i][1]=++vid;
            addedge(S,id[i][0],1,0);
            addedge(id[i][1],T,1,0);
        }
        
        for(int i=1,j,d;i<=n;i++)  
            while(scanf("%d",&j) && j) {
                scanf("%d",&d);
                addedge(id[i][0],id[j][1],1,d);
            }
        return true;
    }
    return false;
}

bool SPFA() {
    int u,l,r;
    l=r=0;
    memset(dist,0x3f,sizeof(dist));
    dist[S]=0;
    inque[q[r++]=S]=1;
    while(l<r) {
        inque[u=q[l++]]=0;
        for(int i=g[u];~i;i=nex[i]) 
            if(f[i] && dist[v[i]]>dist[u]+c[i]) {
            dist[v[i]]=dist[u]+c[i];
            pre[v[i]]=i;
            if(!inque[v[i]]) inque[q[r++]=v[i]]=1;
        }
    }
    return dist[T]<inf;
}

int augment() {
    int aug=inf,res=0;
    for(int i=T;i!=S;i=v[pre[i]^1]) aug=min(aug,f[pre[i]]);
    for(int i=T;i!=S;i=v[pre[i]^1]) {
        f[pre[i]]-=aug;
        f[pre[i]^1]+=aug;
        res+=aug*c[pre[i]];
    }
    ans+=aug;
    return res;
}

void solve() {
    ans=0;
    int res=0;
    while(SPFA()) res+=augment();
    if(ans!=n) printf("N
");
    else printf("%d
",res);    
}

int main() {
    while(build()) solve();
    return 0;
}
原文地址:https://www.cnblogs.com/invoid/p/5574176.html