hdu 3917 Road construction

  1 /*
  2 hdu 3917 Road constructions 最大权闭合图
  3 题意:n个城市 m个工程公司修路 每个公司要交税收 有k个路段 分别花销cost
  4       当如果选择了某个公司,该公司负责的所有的路都要选,还有如果1->2的路由公司A负责,
  5       2->3的路由公司B负责,那么如果选了公司A就必须选公司B, 求最大的收益
  6 建图:税收为正权值、cost为负权值 start连所有公司m end连所有公司m
  7        规则要求联系的公司之间为INF eg addedge(a,b,INF);该处解决方法建结构体详见具体代码
  8        start=0;end=1+m;totals=end+1;
  9        建图完成
 10 答案:最大权闭合图。一模一样的。答案为税收总和-最大流
 11 */
 12 #include <iostream>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<vector>
 16 #include<queue>
 17 #include<algorithm>
 18 using namespace std;
 19 #define min(a,b) ((a)<(b))?(a):(b)
 20 #define max(a,b) ((a)>(b))?(a):(b)
 21 #define MAXN 6005//尽量开大点
 22 #define MAXM  100002 //M取N的平方倍或者N*9
 23 #define INF 0x3f3f3f3f
 24 int m,n;
 25 struct node
 26 {
 27     int n;//点编号
 28     int w;//点权
 29 }Node[MAXM];//n变m
 30 //链式前向星
 31 struct s//存工程每个工程公司修路的起点终点
 32 {
 33     int s;//起点
 34     int t;//终点
 35     int c;//该公司名称
 36 }ss[MAXN];
 37 struct enode
 38 {
 39     int t;
 40     int w;                //权值
 41     int c;                //流量
 42 //  int cost;
 43 //    int pre;            //前向指针
 44     int next;
 45 };
 46 
 47     struct enode e[MAXM];
 48     int box[MAXN],ecnt;
 49     //int etail[MAXN];        //尾部
 50     void init()
 51     {
 52         ecnt=0;
 53         memset(box,-1,sizeof(box));
 54     //    memset(etail,-1,sizeof(etail));        //初始化尾部
 55     }
 56     void addedge(int f,int t,int c)            //流量重载
 57     {
 58         e[ecnt].next=box[f];
 59         e[ecnt].t=t;
 60         e[ecnt].c=c;
 61         box[f]=ecnt++;
 62         e[ecnt].next=box[t];
 63         e[ecnt].t=f;
 64         e[ecnt].c=0;
 65         box[t]=ecnt++;
 66     }
 67 int sap(int s,int t,int N)//最大流问题
 68 {
 69     int gap[MAXN],lvl[MAXN],cur[MAXN],pre[MAXN];
 70     int curflow,ans=0,u,tmp,neck,i;
 71     memset(lvl,0,sizeof(lvl));
 72     memset(gap,0,sizeof(gap));
 73     memset(pre,-1,sizeof(pre));
 74     for(i=0;i<N;i++)
 75         cur[i]=box[i];
 76     gap[0]=N;
 77     u=s;
 78     while(lvl[s]<N)
 79     {
 80         if(u==t)
 81         {
 82             curflow=INF;
 83             for(i=s;i!=t;i=e[cur[i]].t)
 84             {
 85                 if(curflow>e[cur[i]].c)
 86                 {
 87                     neck=i;
 88                     curflow=e[cur[i]].c;
 89                 }
 90             }
 91             for(i=s;i!=t;i=e[cur[i]].t)
 92             {
 93                 tmp=cur[i];
 94                 e[tmp].c-=curflow;
 95                 e[tmp^1].c+=curflow;
 96             }
 97             ans+=curflow;
 98             u=neck;
 99         }
100         for(i=cur[u];i!=-1;i=e[i].next)
101             if(e[i].c && lvl[u]==lvl[e[i].t]+1)
102                 break;
103         if(i!=-1)
104         {
105             cur[u]=i;
106             pre[e[i].t]=u;
107             u=e[i].t;
108         }
109         else
110         {
111             if(--gap[lvl[u]]==0)
112                 break;
113              cur[u]=box[u];
114             for(tmp=N,i=box[u];i!=-1;i=e[i].next)
115                 if(e[i].c)
116                     tmp=min(tmp,lvl[e[i].t]);
117             lvl[u]=tmp+1;
118             gap[lvl[u]]++;
119             if(u!=s)
120                 u=pre[u];
121         }
122     }
123     return ans;
124 }
125 int index[5010];
126 int main()
127 {
128      int a,b,c,d,t,k,w,ct;
129      int i,j;
130      int start,end,ans;
131    while(scanf("%d%d",&n,&m)&&n&&m)  //;
132    {
133         // if(m==0&&n==0)break;
134          start=ans=ct=0;
135          end=1+m;//终点编号
136          init();
137          memset(index,0,sizeof(index));
138          for(i=1;i<=m;i++)
139          {
140              scanf("%d",&w);
141              addedge(start,i,w);//起点连公司 税收为正值
142              ans+=w;//正权值累加
143          }
144          scanf("%d",&k);
145          for(i=1;i<=k;i++)
146          {
147                scanf("%d%d%d%d",&a,&b,&c,&d);
148                ss[i].s=a; ss[i].t=b;
149                ss[i].c=c;
150                index[c]+=d;//对应工程公司付费求和 减小建边次数
151                //addedge(c,end,d);
152          }
153         for(i=1;i<=m;i++)
154          {
155              addedge(i,end,index[i]);//公司连终点
156          }
157          for(i=1;i<=k;i++)//k个公路条件
158          {
159              for(j=1;j<=k;j++)
160              {
161                  if(ss[i].t==ss[j].s&&(i!=j)&&ss[i].c!=ss[j].c)
162                  {
163                     addedge(ss[i].c,ss[j].c,INF);
164                  }
165              }
166          }
167          
168          t=sap( start,end,end+1);
169          printf("%d\n",ans-t);
170    }
171     return 0;
172 }
173 /*
174 4 2
175 500 10
176 4
177 1 2 1 10
178 2 3 1 20
179 4 3 1 30
180 1 4 2 60
181 4 2
182 500 100
183 5
184 1 2 1 10
185 2 3 1 20
186 4 3 1 30
187 4 3 2 10
188 1 4 2 60
189 3 1
190 10
191 3
192 1 2 1 100
193 2 3 1 100
194 3 1 1 100
195 0 0
196 
197 
198 
199 Sample Output
200 
201 440
202 470
203 0
204 */
//http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?cid=4456&pid=1010&ojid=0

 

posted on 2013-04-22 21:18  ACM_Someone like you  阅读(347)  评论(3编辑  收藏  举报

导航