标签:
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 6354 Accepted Submission(s): 1995
题意:从最西边点到最东边点的最大流,双向图
wa哭了。
1 #pragma comment(linker, "/STACK:102400000,102400000") // 固定格式,中间不能有空格,防止RE,爆栈,只能用C++提交 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<algorithm> 7 8 using namespace std; 9 10 #define N 1350000 11 #define INF 0xfffffff 12 13 struct node 14 { 15 int v, flow, next; 16 }edge[N]; 17 18 int cnt, head[N], layer[N]; 19 20 void addedge(int u, int v, int flow) 21 { 22 edge[cnt].v = v; 23 edge[cnt].flow = flow; 24 edge[cnt].next = head[u]; 25 head[u] = cnt; 26 cnt++; 27 28 swap(v, u); 29 30 edge[cnt].v = v; 31 edge[cnt].flow = flow; 32 edge[cnt].next = head[u]; 33 head[u] = cnt; 34 cnt++; 35 } 36 // bfs分层,构图 37 int bfs(int u, int e) // 函数写在主函数后也TLE。。写前边~, 38 { 39 memset(layer, 0, sizeof(layer)); 40 queue<int> Q; 41 Q.push(u); 42 layer[u] = 1; 43 44 while(Q.size()) 45 { 46 u = Q.front(); 47 Q.pop(); 48 49 if(u == e) 50 return true; 51 for(int i = head[u]; i != -1; i = edge[i].next) 52 { 53 int v = edge[i].v; 54 55 if(edge[i].flow && !layer[v]) 56 { 57 layer[v] = layer[u]+1; 58 Q.push(v); 59 } 60 } 61 } 62 return false; 63 } 64 65 int dfs(int u, int Maxflow, int e) 66 { 67 int flow; 68 69 if(u == e) 70 return Maxflow; 71 72 int uflow = 0; 73 74 for(int i = head[u]; i != -1; i = edge[i].next) 75 { 76 int v = edge[i].v; 77 if(layer[v] == layer[u]+1 && edge[i].flow) 78 { 79 flow = min(Maxflow-uflow, edge[i].flow); // 路径总流量减去从这分叉开的其他路的流量就是可能流过这个点的流量,取能流的最小值 80 flow = dfs(v, flow, e); 81 82 edge[i].flow -= flow; 83 edge[i^1].flow += flow; 84 85 uflow += flow; //有可能找到不止一条路 86 87 if(uflow == Maxflow) 88 break; 89 } 90 } 91 if(uflow == 0) 92 layer[u] = 0; 93 return uflow; 94 } 95 96 int dinic(int s, int e) // dinic 97 { 98 int ans = 0; 99 100 while(bfs(s, e)) 101 ans += dfs(s, INF, e); 102 return ans; 103 } 104 105 int main() 106 { 107 int c, n, m, x, y, s, e, u, v, flow; 108 109 scanf("%d", &c); 110 111 while(c--) 112 { 113 cnt = 0; 114 memset(head, -1, sizeof(head)); 115 116 scanf("%d%d", &n, &m); 117 int west = INF, east = -INF; 118 119 for(int i = 1; i <= n; i++) 120 { 121 scanf("%d%d", &x, &y); 122 if(x < west) 123 west = x, s = i; 124 if(x > east) 125 east = x, e = i; // 找最西边还有最东边的点 126 } 127 while(m--) 128 { 129 scanf("%d%d%d", &u, &v, &flow); 130 addedge(u, v, flow); // 只能写一个addedge不然tle 131 //addedge(v, u, flow); 132 } 133 printf("%d\n", dinic(s, e)); 134 } 135 return 0; 136 }
标签:
原文地址:http://www.cnblogs.com/Tinamei/p/4732886.html