您的位置:首页 > 理论基础 > 计算机网络

ZOJ 3792 - Romantic Value (网络流‘最小割)

2015-07-20 18:32 567 查看
题目:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5300

题意:

n个点,m条边,起点s终点t,构成无向图。

为了使得两个点无法联通,删去的边的权值最小且边数最少,求出剩下的边总权值/ 删去的边数。

思路:

最小割。

边权 c = c*10000+1;

flow/10000 为删去的边权值,flow%10000 为删去的边数。

AC.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f;
const int maxn = 200;
const int maxm = 4000;

int n, m;
struct edge {
int to, cap, rev;
edge(int t, int c, int r) {
to = t; cap = c; rev = r;
}
};
vector<edge> G[2*maxn];
bool used[2*maxn];
int sum;

void init()
{
sum = 0;
for(int i = 0; i <= n; ++i) {
G[i].clear();
}
}

void addedge(int from, int to, int cap)
{
G[from].push_back(edge(to, cap, G[to].size()));
G[to].push_back(edge(from, 0, G[from].size()-1));
}

int dfs(int v, int t, int f)
{
if(v == t) return f;
used[v] = true;
for(int i = 0; i < G[v].size(); ++i) {
edge &e = G[v][i];
if(!used[e.to] && e.cap > 0) {
int d = dfs(e.to, t, min(f, e.cap));
if(d > 0) {
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}

int max_flow(int s, int t)
{
int flow = 0;
while(1) {
memset(used, 0, sizeof(used));
int f = dfs(s, t, INF);
if(f == 0) return flow;
flow += f;
sum++;
}
return flow;
}

int main()
{
//freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
int s, t;
scanf("%d %d %d %d", &n, &m, &s, &t);

init();
int ss = 0;
for(int i = 0; i < m; ++i) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
ss += w;
addedge(u, v, w*10000+1);
addedge(v, u, w*10000+1);
}

int f = max_flow(s, t);
int res = ss - f/10000;
int bn = f%10000;
if(res == ss) {
printf("Inf\n");
}
else {
double ans = (double)res/bn;
printf("%.2lf\n", ans);
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ZOJ