zoukankan      html  css  js  c++  java
  • 【NEERC 2003】有向图破坏

    【题目描述】

    Alice和Bob正在玩如下的游戏。首先Alice画一个有N个顶点,M条边的有向图。然后Bob试着摧毁它。在一次操作中他可以找到图中的一个点,并且删除它所有的入边或所有的出边。

    Alice给每个点定义了两个值:Wi+和Wi-。如果Bob删除了第i个点所有的入边他要给Alice付Wi+元,如果他删除了所有的出边就需要给Alice付Wi元。

    找到Bob删除图中所有边需要的最小花费。

    【输入格式】

    输入数据描述了Alice画下的图。

    输入文件的第一行有两个数N,M(1<=N<=100,1<=M<=5000)。第二行有N个整数,描述了N个点的Wi+,同样的第三行是这N个点的Wi-。所有的费用都是正数并且不超过10^6。接下来的M行每行有两个数,代表有向图中相应的一条边。

    【输出格式】

    输出一行一个整数,即Bob的最小花费。

    【分析】

    很容易想到,把每个点拆成两个点,一个控制出边,一个控制入边,保留原边后很明显的一个最小权点覆盖集,Dinic就行了。

     1 #include <cstdlib>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <queue>
     6 const int maxn=500;
     7 const int INF=10000*10000;
     8 using namespace std;
     9 struct tu
    10 {
    11        int c,f;
    12        tu(){c=0;f=0;}
    13 }maps[maxn][maxn];
    14 int dist[maxn],n,m;
    15 
    16 void Dinic();
    17 bool BFS();//构建层次网络 
    18 int dfs(int v,int low);
    19 
    20 int main()
    21 {
    22     int i;
    23     //文件操作
    24     freopen("destroyingthegraph.in","r",stdin);
    25     freopen("destroyingthegraph.out","w",stdout);
    26     memset(maps,0,sizeof(maps));
    27     
    28     scanf("%d%d",&n,&m);//n个点,m条边 
    29     
    30     for (i=1;i<=n;i++) scanf("%d",&maps[i+n][2*n+1].c);//w+
    31     for (i=1;i<=n;i++) scanf("%d",&maps[0][i].c);//w-
    32     
    33     for (i=1;i<=m;i++) 
    34     {
    35         int u,v;
    36         scanf("%d%d",&u,&v);
    37         maps[u][v+n].c=INF;
    38     }
    39     Dinic();
    40     return 0;
    41 }
    42 void Dinic()
    43 {
    44      int flow=0;
    45      while ( BFS() )
    46      {
    47            int temp=0;
    48            if (temp=dfs(0,INF)) flow+=temp;
    49      }
    50      printf("%d
    ",flow);
    51 }
    52 bool BFS()//层次网络
    53 {
    54      queue<int>Q;
    55      int i;
    56      memset(dist,-1,sizeof(dist));
    57      dist[0]=0;
    58      Q.push(0);
    59      while (!Q.empty())
    60      {
    61            int u=Q.front();Q.pop();
    62            for (i=0;i<=(2*n+1);i++)
    63            {
    64                int v=i;
    65                if(maps[u][v].c-maps[u][v].f>0 && dist[v]==-1)
    66                {
    67                   dist[v]=dist[u]+1;
    68                   Q.push(v);
    69                } 
    70            } 
    71      }
    72      return (dist[(2*n)+1]!=-1);
    73 } 
    74 int dfs(int u,int low)
    75 {
    76      if (u==(2*n)+1 || low==0) return low;
    77      int flow=0,f,i;
    78      for (i=0;i<=(2*n)+1;i++)
    79      {
    80          int v=i;
    81          if (maps[u][v].c>maps[u][v].f && dist[v]==dist[u]+1)
    82          {
    83              if (f=dfs(i,min(low,maps[u][v].c-maps[u][v].f)))
    84              {
    85                  maps[u][v].f+=f;
    86                  maps[v][u].f-=f;
    87                  low-=f;
    88                  flow+=f;
    89                  if (low==0) break;
    90              }
    91          }
    92      }
    93      return flow;
    94 }
    View Code
  • 相关阅读:
    构建maven的web项目时注意的问题(出现Error configuring application listener of class org.springframework.web.context.ContextLoaderListener 或者前端控制器无法加载)
    c3p0私有属性checkoutTimeout设置成1000引发的调试错误:
    sql面试题(学生表_课程表_成绩表_教师表)
    传值与传址
    new String()理解
    hashcode的理解
    CentOs安装ssh服务
    openstack swift memcached
    openstack swift middleware开发
    java实现二叉树
  • 原文地址:https://www.cnblogs.com/hoskey/p/3726425.html
Copyright © 2011-2022 走看看