#include <utility>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <bitset>
#include <map>
#include <iterator>
using namespace std;
#define clr(a,v) memset(a,v,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF = 0x7f7f7f7f;
const int maxn = 411;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int mod = 777777777;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
struct node {
int v, next;
double w;
node() {
}
node(int v, int next, double w) :
v(v), next(next), w(w) {
}
} edge[211111];
double dblcmp(double x) {
if (x < -eps)
return -1;
return x > eps;
}
int E, head[maxn], n, dis[maxn], cur[maxn], pre[maxn], gap[maxn];
bool vis[maxn];
int cut[maxn], cnt;
template<typename T>
T minx(T a, T b) {
return (a == -1 || b < a) ? b : a;
}
void init() {
E = 0;
clr(head, -1);
}
void add_edge(int u, int v, double c, double r) {
edge[E] = node(v, head[u], c - r);
head[u] = E++;
edge[E] = node(u, head[v], 0);
head[v] = E++;
}
double sap(int s, int t, int n) {
int i;
clr(gap, 0);
clr(dis, 0);
gap[0] = n;
for (i = 0; i <= n; ++i)
cur[i] = head[i];
int u = pre[s] = s, v;
double maxflow = 0, aug = -1;
while (dis[s] < n) {
loop: for (i = cur[u]; ~i; i = edge[i].next) {
v = edge[i].v;
if (dblcmp(edge[i].w) > 0 && dis[u] == dis[v] + 1) {
aug = minx(aug, edge[i].w);
cur[u] = i;
pre[v] = u;
u = v;
if (u == t) {
for (u = pre[u]; v != s; v = u, u = pre[u]) {
edge[cur[u]].w -= aug;
edge[cur[u] ^ 1].w += aug;
}
maxflow += aug;
aug = -1;
}
goto loop;
}
}
int mindis = n;
for (i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
if (dblcmp(edge[i].w) > 0 && mindis > dis[v]) {
mindis = dis[v];
cur[u] = i;
}
}
if ((--gap[dis[u]]) == 0)
break;
gap[dis[u] = mindis + 1]++;
u = pre[u];
}
return maxflow;
}
double c[maxn<<2];
void dfs(int u) {
vis[u] = true;
int i, v;
for (i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
if (vis[v])
continue;
if (dblcmp(edge[i].w) > 0) {
dfs(v);
}
}
}
double MinCut() {
clr(vis, false);
cnt = 0;
dfs(1);
double w = 0;
for (int i = 0; i < cnt; i += 2)
w += c[cut[i] << 1];
return w * 1.0 / cnt;
}
int u[maxn<<2], v[maxn<<2];
int main() {
ios::sync_with_stdio(false);
int n, m, i;
while (~scanf("%d%d", &n, &m)) {
init();
for (i = 0; i < m; ++i) {
scanf("%d%d%lf", u + i, v + i, c + i);
add_edge(u[i], v[i], c[i], 0);
}
//double r = sap(1, n, n);
double l, r, mid;
l = 0, r = 1e7;
double res = 0;
while (r - l > eps) {
mid = (l + r) * 0.5;
init();
res = 0;
for (i = 0; i < m; ++i) {
add_edge(u[i], v[i], c[i], mid);
add_edge(v[i], u[i], c[i], mid);
if (c[i] - mid < 0)
res += c[i] - mid;
}
res += sap(1, n, n);
if (dblcmp(res) < 0)
r = mid;
else
l = mid;
}
cnt = 0;
init();
for (i = 0; i < m; ++i) {
add_edge(u[i], v[i], c[i], mid);
add_edge(v[i], u[i], c[i], mid);
if (c[i] - mid < 0) {
res += c[i] - mid;
cut[cnt++] = i + 1;
}
}
res += sap(1, n, n);
clr(vis, false);
dfs(1);
for (i = 0; i < E; ++i) {
if (vis[edge[i].v] ^ vis[edge[i ^ 1].v])
cut[cnt++] = (i >> 2) + 1;
}
sort(cut, cut + cnt);
cnt = unique(cut, cut + cnt) - cut;
printf("%d\n", cnt);
for (i = 0; i < cnt; ++i) {
printf("%d%c", cut[i], i == cnt - 1 ? '\n' : ' ');
}
}
return 0;
}
ZOJ Problem Set - 2676 Network Wars
最新推荐文章于 2018-06-04 13:57:00 发布