HDU 3491 Thieves

题意:给出一张无向图,每个点上都有一个权值,然后让你删掉权值之和尽量小的点,使得S到H不连通。

无向图带权点连通度问题。每个点拆点,容留为点权,对于原来图中的无向边(u,v),拆成两条边(u',v,inf),(v',u,inf),跑S'到T 的maxflow就可以了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define INF 1<<30
 6 #define maxn 210
 7 #define maxm 30000
 8 using namespace std;
 9 
10 int v[maxm],next[maxm],w[maxm];
11 int first[maxn],d[maxn],work[maxn],q[maxn];
12 int e,S,T,n,m;
13 
14 void init(){
15     e = 0;
16     memset(first,-1,sizeof(first));
17 }
18 
19 void add_edge(int a,int b,int c){
20     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
21     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
22 }
23 
24 int bfs(){
25     int rear = 0;
26     memset(d,-1,sizeof(d));
27     d[S] = 0;q[rear++] = S;
28     for(int i = 0;i < rear;i++){
29         for(int j = first[q[i]];j != -1;j = next[j])
30             if(w[j] && d[v[j]] == -1){
31                 d[v[j]] = d[q[i]] + 1;
32                 q[rear++] = v[j];
33                 if(v[j] == T)   return 1;
34             }
35     }
36     return 0;
37 }
38 
39 int dfs(int cur,int a){
40     if(cur == T)    return a;
41     for(int &i = work[cur];i != -1;i = next[i]){
42         if(w[i] && d[v[i]] == d[cur] + 1)
43             if(int t = dfs(v[i],min(a,w[i]))){
44                 w[i] -= t;w[i^1] += t;
45                 return t;
46             }
47     }
48     return 0;
49 }
50 
51 int dinic(){
52     int ans = 0;
53     while(bfs()){
54         memcpy(work,first,sizeof(first));
55         while(int t = dfs(S,INF))   ans += t;
56     }
57     return ans;
58 }
59 
60 int main()
61 {
62     int kase;
63     scanf("%d",&kase);
64     while(kase--){
65         scanf("%d%d%d%d",&n,&m,&S,&T);
66         S += n;
67         init();
68         for(int i = 1;i <= n;i++){
69             int tmp;
70             scanf("%d",&tmp);
71             add_edge(i,i+n,tmp);
72         }
73         for(int i = 1;i <= m;i++){
74             int a,b;
75             scanf("%d%d",&a,&b);
76             add_edge(a+n,b,INF);
77             add_edge(b+n,a,INF);
78         }
79         printf("%d\n",dinic());
80     }
81     return 0;
82 }
View Code

 

posted @ 2013-10-30 17:12  浙西贫农  阅读(155)  评论(0编辑  收藏  举报