zoukankan      html  css  js  c++  java
  • 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
    ",dinic());
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    使用paramiko的问题记录
    python常见异常及解决方法
    linux ps -aux各列含义
    常用技能
    超时程序管理
    跨年的总结和展望
    java json和对象互转
    一些常用功能总结
    ResultSet转成java类对象
    python常用功能总结
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3397311.html
Copyright © 2011-2022 走看看