• HDU 3251 Being a Hero


    题意:一个国家的地图是一张n个点m条边的有向图。你保卫了国家成为了英雄,现在国王答应给你一些城市。国王居住在首都,编号为1,但他不想随意的到达你的领地,所以你必须破坏一些路,使得从首都到你所拥有的所有城市不连通。而破坏这些路需要花钱。国王给了你f个城市供你选择,每个城市有一个价值。你最后的总收益=你选择的城市的价值之和-破坏路花费的钱。现在让你输出最大的收益,以及完成这样的收益应该破坏哪些路。

    首先对于表示这个国家地图的有向边(u,v,cost),直接在图中建一条一样的边(u,v,cost)。对于供你选择的城市i,假设它的价值是value,创建一个汇点T,建一条(i,T,value)的边。然后以1为源点,T为汇点,求最小割即可。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define INF 1<<30
      6 #define maxn 1010
      7 #define maxm 300000
      8 using namespace std;
      9 
     10 int u[maxm],v[maxm],next[maxm],w[maxm];
     11 int first[maxn],d[maxn],work[maxn],q[maxn],vis[maxn];
     12 int e,S,T,n,m,f;
     13 bool f1[maxn],f2[maxn];
     14 
     15 void init(){
     16     e = 0;
     17     memset(first,-1,sizeof(first));
     18 }
     19 
     20 void add_edge(int a,int b,int c){
     21     u[e] = a;v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
     22     u[e] = b;v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
     23 }
     24 
     25 int bfs(){
     26     int rear = 0;
     27     memset(d,-1,sizeof(d));
     28     d[S] = 0;q[rear++] = S;
     29     for(int i = 0;i < rear;i++){
     30         for(int j = first[q[i]];j != -1;j = next[j])
     31             if(w[j] && d[v[j]] == -1){
     32                 d[v[j]] = d[q[i]] + 1;
     33                 q[rear++] = v[j];
     34                 if(v[j] == T)   return 1;
     35             }
     36     }
     37     return 0;
     38 }
     39 
     40 int dfs(int cur,int a){
     41     if(cur == T)    return a;
     42     for(int &i = work[cur];i != -1;i = next[i]){
     43         if(w[i] && d[v[i]] == d[cur] + 1)
     44             if(int t = dfs(v[i],min(a,w[i]))){
     45                 w[i] -= t;w[i^1] += t;
     46                 return t;
     47             }
     48     }
     49     return 0;
     50 }
     51 
     52 int dinic(){
     53     int ans = 0;
     54     while(bfs()){
     55         memcpy(work,first,sizeof(first));
     56         while(int t = dfs(S,INF))   ans += t;
     57     }
     58     return ans;
     59 }
     60 
     61 void dfs1(int u){
     62     f1[u] = 1;
     63     for(int i = first[u];i != -1;i = next[i]){
     64         if(!f1[v[i]] && w[i])   dfs1(v[i]);
     65     }
     66 }
     67 
     68 void dfs2(int u){
     69     f2[u] = 1;
     70     for(int i = first[u];i != -1;i = next[i]){
     71         if(!f2[v[i]] && w[i^1]) dfs2(v[i]);
     72     }
     73 }
     74 
     75 int p[100010],res[100010];
     76 
     77 void min_cnt(){
     78     memset(f1,0,sizeof(f1));
     79     memset(f2,0,sizeof(f2));
     80     dfs1(S);
     81     dfs2(T);
     82     /*for(int i = 1;i <= n;i++)
     83         printf("f1[%d] = %d
    ",i,f1[i]);
     84     for(int i = 1;i <= n;i++)
     85         printf("f2[%d] = %d
    ",i,f2[i]);*/
     86     int cnt = 0;
     87     for(int i = 1;i <= m;i++){
     88         if(f1[u[p[i]]] && f2[v[p[i]]] && !w[p[i]]){
     89             res[cnt++] = i;
     90         }
     91     }
     92     printf("%d",cnt);
     93     for(int i = 0;i < cnt;i++)  printf(" %d",res[i]);
     94     printf("
    ");
     95 }
     96 
     97 int main()
     98 {
     99     int nkase;
    100     scanf("%d",&nkase);
    101     for(int kase = 1;kase <= nkase;kase++){
    102         init();
    103         int sum = 0;
    104         scanf("%d%d%d",&n,&m,&f);
    105         S = 1,T = n+1;
    106         for(int i = 1;i <= m;i++){
    107             int a,b,c;
    108             scanf("%d%d%d",&a,&b,&c);
    109             p[i] = e;
    110             add_edge(a,b,c);
    111         }
    112         for(int i = 1;i <= f;i++){
    113             int a,b;
    114             scanf("%d%d",&a,&b);
    115             sum += b;
    116             add_edge(a,T,b);
    117         }
    118         printf("Case %d: %d
    ",kase,sum-dinic());
    119         min_cnt();
    120     }
    121     return 0;
    122 }
    View Code
  • 相关阅读:
    hdu 1045 Fire Net
    hdu 1044 Collect More Jewels
    hdu 1043 Eight
    hdu 1042 N!
    hdu 1041 Computer Transformation
    hdu 1040 As Easy As A+B
    CI在ngnix的配置
    angularjs表单验证checkbox
    chrome浏览器跨域设置
    angularjs向后台传参,后台收不到数据
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3398053.html
Copyright © 2020-2023  润新知