Road constructions (hdu 3917 最大权闭合图)

Road constructions

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1436    Accepted Submission(s): 467

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

2011 Multi-University Training Contest 8 - Host
by HUST

Recommend

lcy   |   We have carefully selected several similar problems for you:  3657 3915 3914 3913 3918

题意:N个城市,m条道路需要建设,每条道路由某个公司负责并花费一定的费用,每个公司会向国家纳税,若公司A造1到2的路,B造2到3的路,那么就说A和B有联系。求国家能得到的钱的最大值。ans=纳税之和-建路花费之和。

思路:做最大权闭合图的题就是要找到有相互依赖关系的两个集合。题目中告诉了公司之间有依赖关系,那么就以公司为节点,源点和每个公司连边权为纳税,公司和会点连边权为花费,公司与公司之间有联系的连边权为INF。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 5005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
const int MAXM = 200010;
typedef long long ll;
using namespace std;

struct Edge
{
    int to,next,cap,flow;
}edge[MAXM];

int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];

void init()
{
    tol=0;
    memset(head,-1,sizeof(head));
}

//加边,单向图三个参数,双向图四个参数
void addedge(int u,int v,int w,int rw=0)
{
    edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u];
    edge[tol].flow=0; head[u]=tol++;
    edge[tol].to=u; edge[tol].cap=rw; edge[tol].next=head[v];
    edge[tol].flow=0; head[v]=tol++;
}

//输入参数:起点,终点,点的总数
//点的编号没有影响,只要输入点的总数
int sap(int start,int end,int N)
{
    memset(gap,0,sizeof(gap));
    memset(dep,0,sizeof(dep));
    memcpy(cur,head,sizeof(head));
    int u=start;
    pre[u]=-1;
    gap[0]=N;
    int ans=0;
    while (dep[start]<N)
    {
        if (u==end)
        {
            int Min=INF;
            for (int i=pre[u];i!=-1;i=pre[edge[i^1].to])
                if (Min>edge[i].cap-edge[i].flow)
                    Min=edge[i].cap-edge[i].flow;
            for (int i=pre[u];i!=-1;i=pre[edge[i^1].to])
            {
                edge[i].flow+=Min;
                edge[i^1].flow-=Min;
            }
            u=start;
            ans+=Min;
            continue;
        }
        bool flag=false;
        int v;
        for (int i=cur[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].to;
            if (edge[i].cap-edge[i].flow && dep[v]+1==dep[u])
            {
                flag=true;
                cur[u]=pre[v]=i;
                break;
            }
        }
        if (flag)
        {
            u=v;
            continue;
        }
        int Min=N;
        for (int i=head[u];i!=-1;i=edge[i].next)
            if (edge[i].cap-edge[i].flow && dep[edge[i].to]<Min)
            {
                Min=dep[edge[i].to];
                cur[u]=i;
            }
        gap[dep[u]]--;
        if (!gap[dep[u]]) return ans;
        dep[u]=Min+1;
        gap[dep[u]]++;
        if (u!=start) u=edge[pre[u]^1].to;
    }
    return ans;
}

struct Node
{
    int u,v,c,cost;
}node[MAXN];

int n,m,num;
int cost[MAXN];

int main()
{
//    freopen("C:/Users/asus1/Desktop/IN.txt","r",stdin);
    int i,j,k,u,v,c,co;
    while (scanf("%d%d",&n,&m),(n+m))
    {
        init();
        int all=0;
        for (i=1;i<=m;i++)
        {
            cost[i]=0;
            scanf("%d",&c);
            addedge(0,i,c);
            all+=c;
        }
        scanf("%d",&k);
        for (i=1;i<=k;i++)
        {
            scanf("%d%d%d%d",&node[i].u,&node[i].v,&node[i].c,&node[i].cost);
            cost[node[i].c]+=node[i].cost;
        }
        for (i=1;i<=m;i++)
            addedge(i,m+1,cost[i]);
        for (i=1;i<=k;i++)
        {
            for (j=1;j<=k;j++)
            {
                if (i!=j)
                {
                    if (node[i].c!=node[j].c&&node[i].v==node[j].u)
                        addedge(node[i].c,node[j].c,INF);
                }
            }
        }
        printf("%d\n",all-sap(0,m+1,m+2));
    }
    return 0;
}
时间: 2024-10-12 11:10:47

Road constructions (hdu 3917 最大权闭合图)的相关文章

hdu 3917 最大权闭合图

/*最大权闭合图: 题意:一些城市需要建路需要一些公司来负责,每个公司需要交一定的税,每条路需要给公司一定的花费,还有一个限制条件,假如说公司a建立了a-b,公司b建立了b-c那么选择 公司a 那么必须选择公司b. 现在要求最大收益. 解:设置一个源点和汇点,将选每个公司的收益和算出来,如果为正值和源点相连,如果为负值和和汇点相连权值为其绝对值,中间的公司之间有关系的权值置为inf, 最大权闭合图=所有正收益的和-最小割. */ #include<stdio.h> #include<st

HDU 3917 最大权闭合图 求最小割

具体参考http://blog.csdn.net/power721/article/details/6665750 TODO 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #define N 8005 5 #define M 1000005 6 #define inf 999999999 7 #define min(a,b) ((a)<(b)?(a):(b)) 8 using namespa

hdu 3061 hdu 3996 最大权闭合图 最后一斩

hdu 3061 Battle :一看就是明显的最大权闭合图了,水提......SB题也不说边数多少....因为开始时候数组开小了,WA....后来一气之下,开到100W,A了.. hdu3996.  gold mine..看了一下,简单题,几乎裸,不敲了.. #include<iostream>//Battle #include<queue> #include<cstdio> #include<cstring> #include<set> #i

hdu 2987最大权闭合图模板类型题

/* 最大权闭合图模板类型的题,考验对知识概念的理解. 题意:现在要辞退一部分员工,辞退每一个员工可以的到一部分利益(可以是负的),并且辞退员工,必须辞退他的下属,求最大利益和辞退的最小人数. 最大权闭合图模板类型. 求出最大权后沿着源点s,dfs到的点就为最小的人数. 证明/* 转载:利用一个经典的trick:多关键字 > 建图前,对所有b[i],执行变换b[i]=b[i]*10000-1,然后,会惊异地发现, > 此时最大流所对应的方案就是满足辞退最少人数的了. > 为什么?显然,变

Base Station (hdu 3879 最大权闭合图)

Base Station Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65768/32768 K (Java/Others) Total Submission(s): 1983    Accepted Submission(s): 838 Problem Description A famous mobile communication company is planning to build a new set of base

hdu 3879 最大权闭合图(裸题)

/* 裸的最大权闭合图 解:参见胡波涛的<最小割模型在信息学竞赛中的应用> */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> using namespace std; #define N 55100//刚开始开的是5100一直越界应该是n+m #define NN 510000 #define inf 0x3fffffff struct node

HDU 3917 Road constructions(最小割---最大权闭合)

题目地址:HDU 3917 这题简直神题意...题目本身就很难看懂不说..即使看懂了,也对这题意的逻辑感到无语...不管了..就按照那题意上说的做吧... 题意:给你n个城市,m个公司,若干条可能要建设的道路,每条有向道路需要花费,还有负责建设这条道路的公司编号,如果要建设ab道路,那么负责这条道路的公司需要建设完它负责的所有道路,而且对负责道路bx(x任意)的公司同样要求,以此类推. 每个公司还要交税,问最多能收多少税. 按照题意来的话,相当于某些公司对某些公司有依赖性.最终的利润==收的税-

Battle (hdu 3061 最大权闭合图模板题)

Battle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 963    Accepted Submission(s): 463 Problem Description 由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅.而他上任的第一天,就面对了一场极其困难的战斗: 据侦查兵回报,前方共有N座城池,考虑到地势原因,最终得到一个结

hdu 3879 hdu 3917 构造最大权闭合图 俩经典题

hdu3879  base station : 各一个无向图,点的权是负的,边的权是正的.自己建一个子图,使得获利最大. 一看,就感觉按最大密度子图的构想:选了边那么连接的俩端点必需选,于是就以边做点,轻轻松松构造了最大权闭合图.简单题.分分钟搞定. hdu3917 :road  constructions :这题题目看了半天没理解...感觉描述的不好...一个有向图,每条路有响应公司承保,若选了该公司,那么该公司的路必需全部选,还有,该公司的承保的路的下面的一条路对应公司也要选,求最大获利.构