Hdu 1853 Cyclic Tour - 最小费用最大流

来源:互联网 发布:sql修改表中的数据 编辑:程序博客网 时间:2024/04/30 20:17

题目描述:给定n个点和m条边,每条边都有权值。判断是否所有的点都在环中。如果是,则输出遍历这些环的最小值;如果没有,就输出-1

题目分析:如果所有的点都在环中,那么这些点的出度等于入度。然后就是网路流了,囧!(orz!)继续学习中...

下面是代码:

#include <stdio.h>#include <string.h>#include <queue>#include <algorithm>using namespace std;const int maxn_v = 400;const int maxn_e = 50000;const int inf = -999999999;const int INF = 999999999;int first[maxn_v],next[maxn_e];int d[maxn_v],vis[maxn_v],pre[maxn_v],preedge[maxn_v];struct edge{  int u;  int v;  int flow;  int cost;} E[maxn_e];int maxflow,mincost;int n,m;int s,t;int e;void add_edge(int u,int v,int flow,int cost){  E[e].u = u;  E[e].v = v;  E[e].flow = flow;  E[e].cost = cost;  next[e] = first[u];  first[u] = e;  e++;  E[e].u = v;  E[e].v = u;  E[e].flow = 0;  E[e].cost = -cost;  next[e] = first[v];  first[v] = e;  e++;}void read_graph(){  e = 0;  s = 0;  t = n + n + 1;  maxflow = 0;  mincost = 0;  for(int i = 0; i < t + 1; i++) first[i] = -1;  for(int i = 0; i < m; i++) {    int u,v,cost;    scanf("%d%d%d",&u,&v,&cost);    add_edge(u,v+n,1,cost);  }  for(int i = 0; i < n; i++) {    add_edge(s,i+1,1,0);    add_edge(i+1+n,t,1,0);  }}void print(){  for(int i = 0; i < e; i++) printf("%d - > %d %d\n",E[i].u,E[i].v,E[i].cost);}bool bellman_ford(){  queue<int> q;  for(int i = 0; i < t + 1; i++) {    d[i] = INF;    vis[i] = 0;    pre[i] = -1;    preedge[i] = -1;  }  d[s] = 0;  q.push(s);  vis[s] = 1;  while(!q.empty()) {    int u = q.front(); q.pop();    vis[u] = 0;    for(int i = first[u]; i != -1; i = next[i]) {      int v = E[i].v;      int cost = E[i].cost;      if(E[i].flow && d[v] > d[u] + cost) {d[v] = d[u] + cost;pre[v] = u;preedge[v] = i;if(!vis[v]) {  vis[v] = 1;  q.push(v);}      }    }  }  if(d[t] >= INF) return false;  return true;}void min_max_flow(){  while(bellman_ford()) {    int minflow = INF;    for(int v = t; v != s; v = pre[v]) {      minflow = min(minflow,E[preedge[v]].flow);    }    //printf("minflow = %d\n",minflow);    for(int v = t; v != s; v = pre[v]) {      E[preedge[v]].flow -= minflow;      E[preedge[v]^1].flow += minflow;    }    maxflow += minflow;    mincost += d[t] * minflow;  }}int main(){  while(~scanf("%d%d",&n,&m)) {    read_graph();    // print();    min_max_flow();    if(maxflow == n) printf("%d\n",mincost);    else printf("-1\n");  }  return 0;}


0 0