标签:
第一道费用流的题目---
其实---还是不是很懂,只知道沿着最短路找增广路
建图
源点到1连一条容量为2(因为要来回),费用为0的边
n到汇点连一条容量为2,费用为0的边
另外的就是题目中输入的了
另外这题是无向边-----
maxn 开到1000会re----
存个模板先吧------------------------------------------
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 #include<set> 7 #include<map> 8 #include<stack> 9 #include<vector> 10 #include<queue> 11 #include<string> 12 using namespace std; 13 14 typedef long long LL; 15 const int maxn = 5000; 16 const int INF = (1 << 30) - 1; 17 18 int first[maxn],vis[maxn],dis[maxn],pos[maxn],ecnt,size; 19 20 struct Edge{ 21 int v,next,cap,cost; 22 } e[10*maxn]; 23 24 void init(){ 25 ecnt = 0; 26 memset(first,-1,sizeof(first)); 27 } 28 29 void add_edge(int u,int v,int cap,int cost){ 30 e[ecnt].v = v; 31 e[ecnt].cap = cap; 32 e[ecnt].cost = cost; 33 e[ecnt].next = first[u]; 34 first[u] = ecnt++; 35 36 e[ecnt].v = u; 37 e[ecnt].cap = 0; 38 e[ecnt].cost = -cost; 39 e[ecnt].next = first[v]; 40 first[v] = ecnt++; 41 } 42 43 bool SPFA(int s, int t) 44 { 45 int u,v,i; 46 queue <int> q; 47 memset(vis,0,sizeof(vis)); 48 for(i= 0;i <= size;i++) dis[i]=INF; 49 50 dis[s]=0; 51 vis[s]=1; 52 q.push(s); 53 54 while(!q.empty()){ 55 u=q.front(); q.pop(); vis[u]=0; 56 for (i = first[u]; ~i;i = e[i].next){ 57 v=e[i].v; 58 if(e[i].cap > 0&& dis[u]+e[i].cost < dis[v]){ 59 dis[v]=dis[u]+e[i].cost; 60 pos[v]=i; 61 if(!vis[v]){ 62 vis[v]=1; 63 q.push(v); 64 } 65 } 66 } 67 } 68 return dis[t] != INF; 69 } 70 71 LL MCMF(int s,int t) 72 { 73 int i; 74 LL cost=0,flow=0; 75 while(SPFA(s,t)){ 76 int d=INF; 77 for (i = t;i != s;i = e[pos[i]^1].v){ 78 d = min(d,e[pos[i]].cap); 79 } 80 for(i = t;i != s;i = e[pos[i]^1].v){ 81 e[pos[i]].cap -= d; 82 e[pos[i]^1].cap += d; 83 } 84 flow += d; 85 cost += dis[t]*d; 86 } 87 return cost; 88 } 89 90 91 int main(){ 92 int n,m; 93 while(scanf("%d %d",&n,&m) != EOF){ 94 init(); 95 size = n+1; 96 add_edge(0,1,2,0); add_edge(1,0,2,0); 97 add_edge(n+1,n,2,0);add_edge(n,n+1,2,0); 98 99 for(int i = 0;i < m;i++){ 100 int u,v,w; 101 scanf("%d %d %d",&u,&v,&w); 102 add_edge(u,v,1,w); 103 add_edge(v,u,1,w); 104 } 105 printf("%I64d\n",MCMF(0,n+1)); 106 } 107 return 0; 108 }
标签:
原文地址:http://www.cnblogs.com/wuyuewoniu/p/4730970.html