uva1658 admiral

Posted invoid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva1658 admiral相关的知识,希望对你有一定的参考价值。

费用流。

裸的拆点最小费用流,一跑就行。

核弹预警,为何wa20多发。build函数一定要返回true。。。。。。

太可怕了

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 5000 + 10 ;
const int maxm = 200000 + 10;
const int inf = 0x3f3f3f3f;
int g[maxn],v[maxm],nex[maxm],c[maxm],f[maxm],eid;
int n,m;
int id[maxn][2],vid,S,T;
int dist[maxn],pre[maxn];
bool inque[maxn];
queue<int> q;

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() {
    memset(id,0,sizeof(id));
    if(!(scanf("%d%d",&n,&m) && n && m)) return false;
    memset(g,-1,sizeof(g)); eid=0; vid=0;
    for(int i=1;i<=n;i++) {
        id[i][0]=++vid;
        id[i][1]=++vid;
        addedge(id[i][0],id[i][1],1,0);
    }
    for(int i=1,u,v,w;i<=m;i++) {
        scanf("%d%d%d",&u,&v,&w);
        if(v!=1 && u!=n) addedge(id[u][1],id[v][0],1,w);
    }
    S=++vid;
    T=++vid;
    addedge(S,id[1][1],2,0);
    addedge(id[n][0],T,2,0);    
    return true;
}

bool SPFA() {
    memset(dist,0x7f,sizeof(dist));
    memset(inque,0,sizeof(inque));
    memset(pre,0,sizeof(pre));
    dist[S]=0;
    q.push(S);
    inque[S]=1;
    int u;
    while(!q.empty()) {
        u=q.front(); q.pop();
        inque[u]=0;
        for(int i=g[u];~i;i=nex[i])  
            if(f[i] && dist[v[i]]>c[i]+dist[u]) {
                dist[v[i]]=c[i]+dist[u];
                pre[v[i]]=i;
                if(!inque[v[i]]) {
                    q.push(v[i]);
                    inque[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+=c[pre[i]]*aug;
    }
    return res;
}

void solve() {
    int res=0;
    while(SPFA()) 
        res+=augment();    
    printf("%d\n",res);    
}

int main() {
    while(build()) solve();
    return 0;
}

以上是关于uva1658 admiral的主要内容,如果未能解决你的问题,请参考以下文章

UVA - 1658 Admiral 海军上将

uva 1658 Admiral (最小费最大流)

UVa1658 Admiral (拆点法,最小费用流)

[题解]uva 1658 Admiral

uva1658 Admiral

UVa 1658,Admiral (拆点+限制最小费用流)