HDU 1853 Cyclic Tour (最小费用最大流+环的判断)

来源:互联网 发布:软件测试免费教程 编辑:程序博客网 时间:2024/05/16 10:13

题目大意:找出图中所有的环并且计算他们的最小环的权值和。


思路:我们可有用费用流的最终流量和图中点数相比较,如果流量==点数,直接输出费用即可。



#include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define LL int#define inf 0x3f3f3f3f#define eps 1e-8#include<vector>#define ls l,mid,rt<<1#define rs mid+1,r,rt<<1|1#define LL __int64using namespace std;const int M = 100100;int cnt,head[110*110];struct node{    int to,w,next,cost;}q[1100*110];int cost,flow;int mp[110][110],n,st,ed,dis[110*3],cur[110*3],f[110*3];bool vis[110*3];void init(){    cnt = 0;    memset(head,-1,sizeof(head));    st = 0,ed = 2*n+1;    cost = flow = 0;}void Add(int a,int b,int cost,int w){    q[cnt].to = b;    q[cnt].w = w;    q[cnt].cost = cost;    q[cnt].next = head[a];    head[a] = cnt++;    q[cnt].to = a;    q[cnt].cost = -cost;    q[cnt].w = 0;    q[cnt].next=head[b];    head[b] = cnt++;}bool SPFA(){    memset(dis,inf,sizeof(dis));    memset(vis,false,sizeof(vis));    memset(cur,-1,sizeof(cur));    f[st] = inf;    queue<int>Q;while(!Q.empty()) Q.pop();    vis[st] = true;dis[st] = 0;Q.push(st);    while(!Q.empty()){        int u = Q.front();        Q.pop();vis[u] = false;        for(int i = head[u];~i;i = q[i].next){            int v = q[i].to;            if(dis[v] > dis[u] + q[i].cost&&q[i].w){                dis[v] = dis[u] + q[i].cost;                f[v] = min(f[u],q[i].w);                cur[v] = i;                if(!vis[v]){                    vis[v] = true;                    Q.push(v);                }            }        }    }    if(dis[ed] >= inf) return false;    flow += f[ed];    cost += f[ed]*dis[ed];    for(int i = cur[ed];~i;i=cur[q[i^1].to ]){        q[i].w -= f[ed];        q[i^1].w += f[ed];    }    return true;}int main(){    int m,i,j,k,a,b,c;    while(~scanf("%d%d",&n,&m)){        if(!m||m==1){            puts("-1");continue;        }        init();        for(i = 1;i <= n;++ i)            for(j = i;j <=n ;++ j)                mp[i][j] = mp[j][i] = inf;        for(i = 0;i < m;++ i ){            scanf("%d%d%d",&a,&b,&c);            if(mp[a][b] > c){                mp[a][b] = c;                Add(a,b+n,c,1);            }        }        for(i = 1;i <= n;++ i)            Add(st,i,0,1);        for(i = 1;i <= n;++ i)            Add(i+n,ed,0,1);        while(SPFA());        if(flow == n)            printf("%d\n",cost);        else            puts("-1");    }    return 0;}


0 0
原创粉丝点击