码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 3917 修路与公司 最大权闭合图 好题

时间:2016-05-20 00:59:31      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

Road constructions

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1590    Accepted Submission(s): 534


Problem Description
N cities are required to connect with each other by a new transportation system. After several rounds of bidding, we have selected M constructions companies and 
decided which section is assigned to which company, the associated cost and the direction of each road. 

Due to the insufficiency of national fiscal revenue and special taxation system (the tax paid by each company pays is a fixed amount and tax payment occurs at the
beginning of the construction of the project)   The government wishes to complete the project in several years and collects as much tax as possible to support the public
expense

For the restrictions of construction and engineering techniques, if a company is required to start the construction, then itself and its associated companies have to 
complete all the tasks they commit (if company A constructs a road 
from city 1 to city 2, company B constructs a road from city 2 to city 3, company C constructs a road from city 1 to city 3, we call 
companies A and B are associated and other company pairs have no such relationship, pay attention, in this example and a are not associated, in other words,’ 
associated‘ is a directed relationship).   
Now the question is what the maximum income the government can obtain in the first year is?
 

 

Input
There are multiple cases (no more than 50).
  Each test case starts with a line, which contains 2 positive integers, n and m (1<=n<=1000, 1<=m<=5000).
  The next line contains m integer which means the tax of each company.
  The Third line has an integer k (1<=k<=3000)which indicates the number of the roads.
  Then k lines fellow, each contains 4 integers, the start of the roads, the end of the road, the company is responsible for this road and the cost of the road.
  The end of the input with two zero
 

 

Output
For each test case output the maximum income in a separate line, and if you can not get any income, please output 0.
 

 

Sample Input
4 2 500 10 4 1 2 1 10 2 3 1 20 4 3 1 30 1 4 2 60 4 2 500 100 5 1 2 1 10 2 3 1 20 4 3 1 30 4 3 2 10 1 4 2 60 3 1 10 3 1 2 1 100 2 3 1 100 3 1 1 100 0 0
 

 

Sample Output
440 470 0
Hint
for second test case, if you choose company 2 responsible ways, then you must choose the path of responsible company 1, but if you choose company 1, then you do not have to choose company 2.
 

 

Source
 

题意:国家现有K条有向路可能被建设(可建可不建),每个有向路由某个公司担任修建,且国家需要支付建设此路的花费,从M个公司中选出一些公司去完成建设  这些被选出的公司所担任修建的所有相关路,如果A公司修u->2,而B公司修2->v,那么选了A公司也必须选B公(即A公司与B公司有关联)。并且这些被选出的公司需要向国家交不同的税,问国家能得到的利益最多是多少。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
int max(int a,int b) {return a>b?a:b;};
int min(int a,int b) {return a<b?a:b;};
struct edge{
   int to,cap,rev;
};

vector<edge> G[5010];
vector<int> st[1010],ed[1010];

int n,m,k,level[5010],sum,iter[5010],cost[5010],tax[5010];

void add_edge(int u,int v,int cap)
{
    G[u].push_back(edge{v,cap,G[v].size()});
    G[v].push_back(edge{u,0,G[u].size()-1});
}

void bfs(int s)
{
    queue<int> q;
    q.push(s);
    level[s]=1;
    while(q.size())
    {
        int now=q.front();q.pop();
        for(int i=0;i<G[now].size();i++)
        if(G[now][i].cap>0)
        {
            edge e=G[now][i];
            if(level[e.to]<0)
              {
                  level[e.to]=level[now]+1;
                  q.push(e.to);
              }
        }
    }
}
int dfs(int s,int t,int minn)
{
    if(s==t)
        return minn;
    for(int &i=iter[s];i<G[s].size();i++)
    {
        edge &e=G[s][i];
        if(level[e.to]>level[s]&&e.cap>0)
        {
            int k=dfs(e.to,t,min(minn,e.cap));
            if(k>0)
             {
                 e.cap-=k;
                 G[e.to][e.rev].cap+=k;
                 return k;
             }
        }
    }
    return 0;
}

int max_flow(int s,int t)
{
    int ans=0,temp;
    for(;;)
    {
        memset(level,-1,sizeof(level));
        bfs(s);
        if(level[t]<0)
            return ans;
        memset(iter,0,sizeof(iter));
        while((temp=dfs(s,t,inf))>0)
            ans+=temp;
    }
    return ans;
}

void build()
{
    for(int i=1;i<=m;i++)
       if(cost[i]>0)
         {
             add_edge(0,i,cost[i]);
             sum+=cost[i];
         }
       else  if(cost[i]<0)
         add_edge(i,m+1,-cost[i]);

    for(int u=1;u<=n;u++)
         for(int i=0;i<st[u].size();i++)
            for(int j=0;j<ed[u].size();j++)
         {
              int a=st[u][i],b=ed[u][j];
              add_edge(b,a,inf);
         }
}

void init()
{
    for(int i=0;i<=m+1;i++) G[i].clear();
    for(int i=1;i<=n;i++)
    {
        st[i].clear();
        ed[i].clear();
    }

    MM(cost,0);
    MM(tax,0);
}

int main()
{
    while(~scanf("%d %d",&n,&m)&&(n||m))
    {
        init();
        sum=0;
        for(int i=1;i<=m;i++)
                scanf("%d",&tax[i]);

        scanf("%d",&k);
        for(int i=1;i<=k;i++)
             {
                 int u,v,b,c;
                 scanf("%d %d %d %d",&u,&v,&b,&c);

                 st[u].push_back(b);
                 ed[v].push_back(b);//st与ed的妙用,,刚开始用的麻烦的爆搜。。
                 cost[b]+=(-c);//切记转换成负数
             }

        for(int i=1;i<=m;i++)
                 cost[i]+=tax[i];//构建的新图中节点值

        build();

        printf("%d\n",sum-max_flow(0,m+1));
    }
    return 0;
}

 

  分析:很好的一道题,,就是原题题意神坑,,再加上把100看成了10,,太不细心了;

1,将原图上无法进行最大权闭合图,,想想就知道了,,转化成公司上的闭合圈最大图(选a公司那么必须选b公司),

2.最大权闭合图中的sum-maxflow中的sum指的是需要跑最小割的新图中节点中值>0的数之和

hdu 3917 修路与公司 最大权闭合图 好题

标签:

原文地址:http://www.cnblogs.com/smilesundream/p/5510665.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!