编程介的小学生 2017-02-10 08:32 采纳率: 20.5%
浏览 757
已采纳

Road constructions

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

  • 写回答

2条回答 默认 最新

  • devmiao 2017-02-13 18:12
    关注
     #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <stdlib.h>
    #include <math.h>
    #include <ctype.h>
    #include <queue>
    #include <map>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    const int INF=0x3f3f3f3f;
    int head[6000], cnt, source, sink, nv, val[6000];
    int d[6000], num[6000], pre[6000], cur[6000];
    struct node
    {
        int u, v, cap, next;
    } edge[1000000];
    void add(int u, int v, int cap)
    {
        edge[cnt].v=v;
        edge[cnt].cap=cap;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    
        edge[cnt].v=u;
        edge[cnt].cap=0;
        edge[cnt].next=head[v];
        head[v]=cnt++;
    }
    void bfs()
    {
        memset(d,-1,sizeof(d));
        memset(num,0,sizeof(num));
        queue<int>q;
        q.push(sink);
        d[sink]=0;
        num[0]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u]; i!=-1; i=edge[i].next)
            {
                int v=edge[i].v;
                if(d[v]==-1)
                {
                    d[v]=d[u]+1;
                    num[d[v]]++;
                    q.push(v);
                }
            }
        }
    }
    int isap()
    {
        memcpy(cur,head,sizeof(cur));
        int flow=0, u=pre[source]=source, i;
        bfs();
        while(d[source]<nv)
        {
            if(u==sink)
            {
                int f=INF, pos;
                for(i=source; i!=sink; i=edge[cur[i]].v)
                {
                    if(f>edge[cur[i]].cap)
                    {
                        f=edge[cur[i]].cap;
                        pos=i;
                    }
                }
                for(i=source; i!=sink; i=edge[cur[i]].v)
                {
                    edge[cur[i]].cap-=f;
                    edge[cur[i]^1].cap+=f;
                }
                flow+=f;
                u=pos;
            }
            for(i=cur[u]; i!=-1; i=edge[i].next)
            {
                if(d[edge[i].v]+1==d[u]&&edge[i].cap)
                {
                    break;
                }
            }
            if(i!=-1)
            {
                cur[u]=i;
                pre[edge[i].v]=u;
                u=edge[i].v;
            }
            else
            {
                if(--num[d[u]]==0) break;
                int mind=nv;
                for(i=head[u]; i!=-1; i=edge[i].next)
                {
                    if(mind>d[edge[i].v]&&edge[i].cap)
                    {
                        mind=d[edge[i].v];
                        cur[u]=i;
                    }
                }
                d[u]=mind+1;
                num[d[u]]++;
                u=pre[u];
            }
        }
        return flow;
    }
    int head1[2000], cnt1;
    struct node1
    {
        int u, v, c, next;
    }city[1000000];
    void add1(int u, int v, int c)
    {
        city[cnt1].v=v;
        city[cnt1].c=c;
        city[cnt1].next=head1[u];
        head1[u]=cnt1++;
    }
    int main()
    {
        int n, m, k, u, v, x, c, sum, i, j, kk;
        while(scanf("%d%d",&n,&m)!=EOF&&(n+m))
        {
            memset(head,-1,sizeof(head));
            memset(head1,-1,sizeof(head1));
            cnt1=0;
            cnt=0;
            source=0;
            sink=m+1;
            nv=sink+1;
            sum=0;
            for(i=1;i<=m;i++)
            {
                scanf("%d",&val[i]);
            }
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d%d%d%d",&u,&v,&x,&c);
                add1(u,v,x);
                val[x]-=c;
            }
            for(i=1;i<=m;i++)
            {
                if(val[i]>0)
                    {
                        add(source,i,val[i]);
                        sum+=val[i];
                    }
                else
                    add(i,sink,-val[i]);
            }
            for(i=1;i<=n;i++)
            {
                for(j=head1[i];j!=-1;j=city[j].next)
                {
                    int v=city[j].v;
                    for(kk=head1[v];kk!=-1;kk=city[kk].next)
                    {
                        add(city[j].c,city[kk].c,INF);
                    }
                }
            }
            int ans=sum-isap();
            printf("%d\n",ans>0?ans:0);
        }
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 r语言神经网络自变量重要性分析
  • ¥15 基于双目测规则物体尺寸
  • ¥15 wegame打不开英雄联盟
  • ¥15 公司的电脑,win10系统自带远程协助,访问家里个人电脑,提示出现内部错误,各种常规的设置都已经尝试,感觉公司对此功能进行了限制(我们是集团公司)
  • ¥15 救!ENVI5.6深度学习初始化模型报错怎么办?
  • ¥30 eclipse开启服务后,网页无法打开
  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计
  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢