题意:

思路:

【费用流】建图:代后

枚举k,求最小费用。

  1 #include<stdio.h>
  2 #include<string.h>
  3
  4 #include <memory.h>
  5 #include <queue>
  6 #define MIN(a , b) ((a) < (b) ? (a) : (b))
  7 using namespace std;
  8 const int inf = 10000010;
  9 const int maxn = 102;
 10 const int maxe = 20000;
 11 const int maxm = 28;
 12 struct node
 13 {
 14     int v,w,c;
 15     int next;
 16 } edge[maxe << 1];
 17 int head[maxn << 1],dis[maxn << 1],pre[maxn << 1],bj[maxn << 1];
 18 int map[maxn][maxn];
 19 bool vis[maxn << 1];
 20 queue <int> Q;
 21 int m,n,k,idx,s,ss,t;
 22
 23 void init()
 24 {
 25     for(int i=0; i<=n; i++)
 26     {
 27         map[i][i] = 0;
 28         for(int j=0; j<=n; j++)
 29         {
 30             map[i][j] = map[j][i] = inf;
 31         }
 32     }
 33     return;
 34 }
 35
 36 void read()
 37 {
 38     int u,v,w;
 39     for(int i=0; i<m; i++)
 40     {
 41         scanf("%d %d %d",&u,&v,&w);
 42         if(map[u][v] > w)
 43         {
 44             map[u][v] = map[v][u] = w;
 45         }
 46     }
 47     return;
 48 }
 49
 50 void floyd()
 51 {
 52     for(int k=0; k<=n; k++)
 53     {
 54         for(int i=0; i<=n; i++)
 55         {
 56             if(i == k || map[i][k] == inf) continue;
 57             for(int j=0; j<=n; j++)
 58             {
 59                 if(j == i || j == k || map[k][j] == inf) continue;
 60                 if(map[i][k] + map[k][j] < map[i][j])
 61                 {
 62                     map[i][j] = map[i][k] + map[k][j];
 63                     map[j][i] = map[i][j];
 64                 }
 65             }
 66         }
 67     }
 68     return;
 69 }
 70
 71 void add(int u,int v,int w,int c)
 72 {
 73     edge[idx].v = v;
 74     edge[idx].w = w;
 75     edge[idx].c = c;
 76     edge[idx].next = head[u];
 77     head[u] = idx++;
 78
 79     edge[idx].v = u;
 80     edge[idx].w = 0;
 81     edge[idx].c = -c;
 82     edge[idx].next = head[v];
 83     head[v] = idx++;
 84     return;
 85 }
 86
 87
 88
 89 bool spfa(int st)
 90 {
 91     memset(vis,false,sizeof(vis));
 92     memset(pre,-1,sizeof(pre));
 93     while(!Q.empty())
 94     {
 95         Q.pop();
 96     }
 97     for(int i=0; i<=t; i++)
 98     {
 99         dis[i] = (i == st) ? 0 : inf;
100     }
101     Q.push(st);
102     vis[st] = true;
103     while(!Q.empty())
104     {
105         int cur = Q.front();
106         Q.pop();
107         vis[cur] = false;
108         for(int i=head[cur]; i != -1; i=edge[i].next)
109         {
110             if(edge[i].w > 0 && dis[edge[i].v] > dis[cur] + edge[i].c)
111             {
112                 dis[edge[i].v] = dis[cur] + edge[i].c;
113                 pre[edge[i].v] = i;
114                 if(vis[edge[i].v] == false)
115                 {
116                     vis[edge[i].v] = true;
117                     Q.push(edge[i].v);
118                 }
119             }
120         }
121     }
122     return dis[t] < inf;
123 }
124
125 int work()
126 {
127     int ans = 0;
128     while(spfa(s))
129     {
130         int dx = inf;
131         int top = t;
132         while(top != s)
133         {
134             dx = MIN(dx , edge[pre[top]].w);
135             top = edge[pre[top]^1].v;
136         }
137         top = t;
138         while(top != s)
139         {
140             ans += dx * edge[pre[top]].c;
141             edge[pre[top]].w -= dx;
142             edge[pre[top]^1].w += dx;
143             top = edge[pre[top]^1].v;
144         }
145     }
146     return ans + n*inf;
147 }
148
149 int mp[maxn][maxn];
150
151 int q;
152
153 void build(int p)
154 {
155    // printf("%d\n",p);
156     memset(head,-1,sizeof(head));
157     memset(bj,-1,sizeof(bj));
158     idx = 0;
159     s = 0;
160     ss = 2*n + 1;
161     t = 2*n + 2;
162     add(s,ss,p,0);
163
164     for (int i=1; i<=n; i++)
165     {
166         if (mp[0][i] < inf)
167             add(ss,i,inf,mp[0][i]);
168         if (mp[i][0] < inf)
169             add(i+n,t,inf,mp[i][0]);
170         add(i,i+n,1,-inf);
171     }
172     for (int i=1; i<=n; i++)
173     {
174         for (int j=i+1; j<=n; j++)
175             if (mp[i][j] < inf)
176             {
177                 add(i+n,j,inf,mp[i][j]);
178             }
179     }
180   //  puts("dfds");
181     return ;
182 }
183
184 int getans()
185 {
186     int res = inf;
187     for (int p=1; p<=q; p++)
188     {
189         build(p);
190         int tmp = work();
191         if (tmp  < res)
192             res = tmp;
193     }
194     return res;
195 }
196
197 int main()
198 {
199     while (scanf("%d%d%d",&n,&m,&q)==3)
200     {
201         if (n == 0 && m== 0)
202             break;
203         for (int i=0; i<=n; i++)
204         {
205             for (int j=0; j<=n; j++)
206             {
207                 mp[i][j] = inf;
208             }
209             mp[i][i] = 0;
210         }
211
212         for (int i=1; i<=m; i++)
213         {
214             int u,v,l;
215             scanf("%d%d%d",&u,&v,&l);
216             if (mp[u][v] > l){
217                 mp[u][v] = l;
218                 mp[v][u] = l;
219             }
220         }
221
222         for (int k=0; k<=n; k++)
223             for (int i=0; i<=n; i++)
224                 for (int j=0; j<=n; j++)
225                     if (mp[i][k] < inf && mp[k][j] < inf)
226                     {
227                         if (mp[i][k] + mp[k][j] < mp[i][j])
228                         {
229                             mp[i][j] = mp[i][k] + mp[k][j];
230                         }
231                     }
232 /*
233         for (int i=0; i<=n; i++)
234         {
235             for (int j=0; j<=n; j++)
236                 printf("%d %d %d\n",i,j,mp[i][j]);
237         }
238
239 */
240         printf("%d\n",getans());
241     }
242     return 0;
243 }

hdu4111

转载于:https://www.cnblogs.com/wangsouc/articles/3273535.html

HDU 4411Arrest(最小费用最大流)相关推荐

  1. hdu 6118 最小费用可行流(注意与最大流的区别)

    题意: 思路:....注意是可行流,在找增广路的时候条件要进行修改....修改的地方看代码注释 代码: #include<bits/stdc++.h> using namespace st ...

  2. HDU 2282 Chocolate (最小费用最大流)

    HDU  2282 Chocolate (最小费用最大流) #include <iostream> #include <cstdio> #include <queue&g ...

  3. HDU 1853 HDU 3488【有向环最小权值覆盖问题 】最小费用最大流

    HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]带权二分图匹配 KM算法 In the kingdom of Henryy, there are N (2 <= N & ...

  4. 【HDU - 6118】度度熊的交易计划(最小费用可行流,网络流费用流变形 )

    题干: 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个 ...

  5. hdu Kaka's Matrix Travels(最小费用最大流)

    把题意写一下:  给你一个n*n的矩阵,每个格子都有一个非负整数,从左上角走到右下角,收集走过的数字,累加,但是只能向右或者向下走,走过之后数字就变为0,让你求从左上角到右下角,走k次之后,所得的最大 ...

  6. HDU 6445 Search for Answer(最小费用最大流-mcmf)

    Description 给出一个nnn个点的完全图的邻接矩阵aaa,其中ai,j=1a_{i,j}=1ai,j​=1表示i,ji,ji,j之间边的方向是iii到jjj,ai,j=0a_{i,j}=0a ...

  7. Going Home HDU - 1533 (最小费用最大流)

    题目链接:https://cn.vjudge.net/problem/HDU-1533 题意:给你n个房子n个人  使得所有人都有一座房子的最小花费 思路:把所有的人与房子建边,最后,源点与所有的人建 ...

  8. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  9. 网络流--最小费用最大流 (理解)

    1.什么是最小费用最大流问题 上篇文章我们讲解了最大流问题,那什么是最小费用最大流呢?听名字就可以看出,我们要在满足最大流的同时找到达成最大流的最小费用. 对于一个网络流,最大流是一定的,但是组成最大 ...

最新文章

  1. 一个CV算法工程师在技术方面的反思!
  2. 如何绘制漂亮的多序列比对图片
  3. hadoop的HDFS-----防火墙导致9870端口无法访问
  4. Qt Creator使用Qt Quick工具栏
  5. Linux 搜狗输入法 候选字乱码
  6. [转]mysql下如何执行sql脚本
  7. go 中 = 与:= 区别
  8. 19.Virtual Type
  9. 怎样设置电脑壁纸_怎样把C盘设置成禁止安装任何软件?教你两个方法,告别电脑卡顿...
  10. python二级通过率_计算机二级考试通过率太低?别担心,是真正备考的人变少了...
  11. element-ui 导航栏三级
  12. c语言输入字符输出数字,C语言——输入一个字符串,将连续数字字符转换为数字...
  13. 教你用Excel做高级甘特图
  14. 全网显示 IP 归属地,是怎么实现的?
  15. 详细解说笔记本电脑怎么录视频
  16. 网页嵌入媒体播放器代码 选择自 murky 的 Blog
  17. 用虚拟机写java程序_JAVA是什么?java是狗屁!写java程序说穿了就是在对java虚拟机这个软件进行应用。...
  18. 设置elment ui plus 的el table的边框线
  19. seq2seq简单总结
  20. kibana java_Kibana安装及使用说明

热门文章

  1. 压缩感知算法_走向纳米光子鼻:一种压缩传感增强型中红外光谱仪
  2. 【新手教程】阿里云视频点播,轻轻松松给网站加上视频的翅膀
  3. 用html和css写一个聚划算页面
  4. springboot毕设项目唐山市大型商场应急预案管理系统b2c1d(java+VUE+Mybatis+Maven+Mysql)
  5. utools工具使用
  6. 机械外骨骼中的恒力悬浮背包研究
  7. 界面/功能都很惊艳:iPad版Office上手体验
  8. 荣耀7刷机android8,荣耀V8升级EMUI5.0+Android7.0
  9. Acrobat Pro DC 教程:如何从 PDF 中提取页面?
  10. 遇见未知的自己 - 张德芬 - 【重要书摘区!】