题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3792
这题是求最小割,但是不会求最小割,龙哥教的权值先*10000+1,利用前向星加边,来储存地图,得到的最大流量/10000,对%10000就是割边
Result | Accepted | ID 3792 | Language C++ | Time 0ms | 352KB |
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #define init(a) memset(a,0,sizeof(a)) const int N = 210; const int maxn = 1000; const int maxm = 5000; #define MIN INT_MIN #define MAX 0x3f3f3f3f #define LL long long using namespace std; int max(int a,int b){if(a>b)return a; else return b;} int min(int a,int b){if(a<b)return a; else return b;} int n,m; int head[maxn],bnum; int dis[maxn]; int num[maxn]; int cur[maxn]; int pre[maxn]; struct node { int v, cap; int next; }edge[maxm]; void add(int u, int v, int cap) { edge[bnum].v=v; edge[bnum].cap = cap; edge[bnum].next = head[u]; head[u]=bnum++; edge[bnum].v=u; edge[bnum].cap=0; edge[bnum].next=head[v]; head[v]=bnum++; } void BFS(int source,int sink) { queue<int>q; while(q.empty()==false) q.pop(); init(num); memset(dis,-1,sizeof(dis)); q.push(sink); dis[sink]=0; num[0]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].v; if(dis[v] == -1) { dis[v] = dis[u] + 1; num[dis[v]]++; q.push(v); } } } } LL ISAP(int source,int sink,int n) { memcpy(cur,head,sizeof(cur)); LL flow=0; int u = pre[source] = source; BFS( source,sink); while( dis[source] < n ) { if(u == sink) { int df = MAX, pos; for(int i = source;i != sink;i = edge[cur[i]].v) { if(df > edge[cur[i]].cap) { df = edge[cur[i]].cap; pos = i; } } for(int i = source;i != sink;i = edge[cur[i]].v) { edge[cur[i]].cap -= df; edge[cur[i]^1].cap += df; } flow += df; u = pos; } int st; for(st = cur[u];st != -1;st = edge[st].next) { if(dis[edge[st].v] + 1 == dis[u] && edge[st].cap) break; } if(st != -1) { cur[u] = st; pre[edge[st].v] = u; u = edge[st].v; } else { if( (--num[dis[u]])==0 ) break; int mind = n; for(int id = head[u];id != -1;id = edge[id].next) { if(mind > dis[edge[id].v] && edge[id].cap != 0) { cur[u] = id; mind = dis[edge[id].v]; } } dis[u] = mind+1; num[dis[u]]++; if(u!=source) u = pre[u]; } } return flow; } void initt() { memset(head,-1,sizeof(head)); bnum=0; } int main() { int T,N,M,P,Q; scanf("%d",&T); while(T--) { initt(); int u,v,w,sum = 0; scanf("%d%d%d%d",&N,&M,&P,&Q); for(int i = 1;i<=M;i++) { scanf("%d%d%d",&u,&v,&w); sum += w; add(u,v,w*10000+1); add(v,u,w*10000+1); } LL ans = ISAP(P,Q,N); if(!ans) { puts("Inf"); continue; } int num = ans/10000; int num1 = ans%10000; //printf("ans = %d num = %d num1 = %d",ans,num,num1); printf("%.2lf\n",(double)(sum-num)/num1); } return 0; }
ZOJ 3792 Romantic Value(ISAP && 最小割),布布扣,bubuko.com
ZOJ 3792 Romantic Value(ISAP && 最小割)
原文:http://blog.csdn.net/wjw0130/article/details/38678487