题意:国王赏赐给你一些城市,但是他不希望可以从首都(编号1)到达任何你的城市。
有m条边连通各个城市,每条边有一个值,为毁掉这条边需要的花费,你的每个城市有一个收入。
问,最后毁掉哪些边,可以使你的收入最高。
思路:将每条边的价值看成流量,连接两个城市,每个你的城市的收入看成流量,与汇点相连。源点为首都(编号1) ,求1-T的最小割。
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2005 #define inf 1<<28 #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define REP(i,s,t) for(int i=(s);i<=(t);++i) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) #define PII pair<int,int> using namespace std; inline void readint(int &ret) { char c; do { c = getchar(); } while(c < '0' || c > '9'); ret = c - '0'; while((c=getchar()) >= '0' && c <= '9') ret = ret * 10 + ( c - '0' ); } struct kdq { int s ,e ,l ,next ; } ed[Max * 100] ; int head[Max] ,num ; void add(int s ,int e ,int l ) { ed[num].s = s ; ed[num].e = e ; ed[num].l = l ; ed[num].next = head[s] ; head[s] = num ++ ; ed[num].s = e ; ed[num].e = s ; ed[num].l = 0 ; ed[num].next = head[e] ; head[e] = num ++ ; } int deep[Max] ; int S, T ; int qe[Max * 100] ; int dinic_bfs() { mem(deep,-1) ; deep[S] = 0 ; int h = 0 , t = 0 ; qe[h ++ ] = S ; while( h > t ) { int tt = qe[t ++ ] ; for (int i = head[tt] ; ~i ; i = ed[i].next ) { int e = ed[i].e ; int l = ed[i].l ; if(l > 0 && deep[e] == -1) { deep[e] = deep[tt] + 1 ; qe[h ++ ] = e ; } } } return deep[T] != -1 ; } int dinic_dfs(int now ,int f) { if(now == T)return f ; int flow = 0 ; for (int i = head[now] ; ~ i ; i = ed[i].next ) { int e = ed[i].e ; int l = ed[i].l ; if(l > 0 && (f - flow ) >0 && deep[e] == deep[now] + 1) { int mm = min(l ,f - flow) ; int nn = dinic_dfs(e,mm) ; flow += nn ; ed[i].l -= nn ; ed[i ^ 1].l += nn ; } } if(!flow) deep[now] = -2 ; return flow ; } int dinic() { int flow = 0 ; while(dinic_bfs()) { flow += dinic_dfs(S,inf) ; } return flow ; } bool vis[Max] ; void dfs(int now)//找与首都相连的城市 { vis[now] = 1 ; for (int i = head[now] ; ~i ; i = ed[i].next ) { int e = ed[i].e ; int l = ed[i].l ; if(l > 0 && !vis[e]) dfs(e) ; } } PII edge[Max * 100] ; int Q[Max] ,Qn ; void init() { mem(head,-1) ; num = 0 ; mem(vis,0) ; Qn = 0 ; } int main() { int t ; readint(t) ; int cas = 0 ; while( t -- ) { init() ; int n , m , f ; readint(n) ; readint(m) ; readint(f) ; S = 1 ; T = n + 1 ; REP(i,0,m - 1) { int a , b , c ; readint(a) ; readint(b) ; readint(c) ; add(a,b,c) ; edge[i].first = a ; edge[i].second = b ; } int sum = 0 ; while( f -- ) { int v ,w ; readint(v) ; readint(w) ; add(v, T ,w) ; sum += w ; } printf("Case %d: %d\n", ++ cas,sum - dinic()) ; dfs(1) ; REP(i,0, m - 1) if(vis[edge[i].first] && !vis[edge[i].second])Q[Qn ++ ] = i + 1 ; printf("%d",Qn) ; REP(i,0,Qn - 1)printf(" %d",Q[i]) ; puts("") ; } return 0; }
作者:kdqzzxxcc 发表于2013-5-9 22:54:27 原文链接
阅读:52 评论:0 查看评论