CodeForces 362E Petya and Pipes

Petya and Pipes

Time Limit: 1000ms

Memory Limit: 262144KB

This problem will be judged on CodeForces. Original ID: 362E
64-bit integer IO format: %I64d      Java class name: (Any)

A little boy Petya dreams of growing up and becoming the Head Berland Plumber. He is thinking of the problems he will have to solve in the future. Unfortunately, Petya is too inexperienced, so you are about to solve one of such problems for Petya, the one he‘s the most interested in.

The Berland capital has n water tanks numbered from 1 to n. These tanks are connected by unidirectional pipes in some manner. Any pair of water tanks is connected by at most one pipe in each direction. Each pipe has a strictly positive integer width. Width determines the number of liters of water per a unit of time this pipe can transport. The water goes to the city from the main water tank (its number is 1). The water must go through some pipe path and get to the sewer tank with cleaning system (its number is n).

Petya wants to increase the width of some subset of pipes by at most k units in total so that the width of each pipe remains integer. Help him determine the maximum amount of water that can be transmitted per a unit of time from the main tank to the sewer tank after such operation is completed.

Input

The first line contains two space-separated integers n and k (2 ≤ n ≤ 50, 0 ≤ k ≤ 1000). Then follow n lines, each line contains n integers separated by single spaces. The i + 1-th row and j-th column contain number cij — the width of the pipe that goes from tank i to tank j (0 ≤ cij ≤ 106, cii = 0). If cij = 0, then there is no pipe from tank i to tank j.

Output

Print a single integer — the maximum amount of water that can be transmitted from the main tank to the sewer tank per a unit of time.

Sample Input

Input

5 70 1 0 2 00 0 4 10 00 0 0 0 50 0 0 0 100 0 0 0 0

Output

10

Input

5 100 1 0 0 00 0 2 0 00 0 0 3 00 0 0 0 4100 0 0 0 0

Output

5

Hint

In the first test Petya can increase width of the pipe that goes from the 1st to the 2nd water tank by 7 units.

In the second test Petya can increase width of the pipe that goes from the 1st to the 2nd water tank by 4 units, from the 2nd to the 3rd water tank by 3 units, from the 3rd to the 4th water tank by 2 units and from the 4th to 5th water tank by 1 unit.

Source

Codeforces Round #212 (Div. 2)

解题:拆边费用流。把原来的边拆成两条,一条流量为原来的,费用为0,另一条费用为1流量为k.

然后进行最小费用路径增广,我们每次增广,d[T】存的是从源到汇,单位流量最便宜的一条路径。。。。一旦费用超过k即停止算法。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 110;
18 struct arc {
19     int to,flow,cost,next;
20     arc(int x = 0,int y = 0,int z = 0,int nxt = -1) {
21         to = x;
22         flow = y;
23         cost = z;
24         next = nxt;
25     }
26 };
27 arc e[10000];
28 int head[maxn],d[maxn],p[maxn],S,T,n,k,tot;
29 bool in[maxn];
30 void add(int u,int v,int flow,int cost) {
31     e[tot] = arc(v,flow,cost,head[u]);
32     head[u] = tot++;
33     e[tot] = arc(u,0,-cost,head[v]);
34     head[v] = tot++;
35 }
36 bool spfa() {
37     queue<int>q;
38     for(int i = 0; i <= n; ++i) {
39         d[i] = INF;
40         p[i] = -1;
41         in[i] = false;
42     }
43     d[S] = 0;
44     q.push(S);
45     while(!q.empty()) {
46         int u = q.front();
47         q.pop();
48         for(int i = head[u]; ~i; i = e[i].next) {
49             if(e[i].flow && d[e[i].to] > d[u] + e[i].cost) {
50                 d[e[i].to] = d[u] + e[i].cost;
51                 p[e[i].to] = i;
52                 q.push(e[i].to);
53             }
54         }
55     }
56     return p[T] > -1;
57 }
58 int solve() {
59     int cost = 0,flow = 0;
60     while(spfa()) {
61         int theMin = INF;
62         for(int i = p[T]; ~i; i = p[e[i^1].to])
63             theMin = min(theMin,e[i].flow);
64         if(cost + d[T]*theMin > k) return flow + (k - cost)/d[T];
65         flow += theMin;
66         cost += d[T]*theMin;
67         for(int i = p[T]; ~i; i = p[e[i^1].to]) {
68             e[i].flow -= theMin;
69             e[i^1].flow += theMin;
70         }
71     }
72     return flow;
73 }
74 int main() {
75     while(~scanf("%d %d",&n,&k)) {
76         memset(head,-1,sizeof(head));
77         S = 0;
78         T = n-1;
79         int tmp;
80         for(int i = tot = 0; i < n; ++i)
81             for(int j = 0; j < n; ++j) {
82                 scanf("%d",&tmp);
83                 if(tmp) {
84                     add(i,j,tmp,0);
85                     add(i,j,k,1);
86                 }
87             }
88         printf("%d\n",solve());
89     }
90     return 0;
91 }

上面代码可以AC,但是忘记标记入队点了。。。。。。^_^..

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 110;
18 struct arc {
19     int to,flow,cost,next;
20     arc(int x = 0,int y = 0,int z = 0,int nxt = -1) {
21         to = x;
22         flow = y;
23         cost = z;
24         next = nxt;
25     }
26 };
27 arc e[10000];
28 int head[maxn],d[maxn],p[maxn],S,T,n,k,tot;
29 bool in[maxn];
30 void add(int u,int v,int flow,int cost) {
31     e[tot] = arc(v,flow,cost,head[u]);
32     head[u] = tot++;
33     e[tot] = arc(u,0,-cost,head[v]);
34     head[v] = tot++;
35 }
36 bool spfa() {
37     queue<int>q;
38     for(int i = 0; i <= n; ++i) {
39         d[i] = INF;
40         p[i] = -1;
41         in[i] = false;
42     }
43     d[S] = 0;
44     q.push(S);
45     while(!q.empty()) {
46         int u = q.front();
47         q.pop();
48         in[u] = false;
49         for(int i = head[u]; ~i; i = e[i].next) {
50             if(e[i].flow && d[e[i].to] > d[u] + e[i].cost) {
51                 d[e[i].to] = d[u] + e[i].cost;
52                 p[e[i].to] = i;
53                 if(!in[e[i].to]){
54                     in[e[i].to] = true;
55                     q.push(e[i].to);
56                 }
57             }
58         }
59     }
60     return p[T] > -1;
61 }
62 int solve() {
63     int cost = 0,flow = 0;
64     while(spfa()) {
65         int theMin = INF;
66         for(int i = p[T]; ~i; i = p[e[i^1].to])
67             theMin = min(theMin,e[i].flow);
68         if(cost + d[T]*theMin > k) return flow + (k - cost)/d[T];
69         flow += theMin;
70         cost += d[T]*theMin;
71         for(int i = p[T]; ~i; i = p[e[i^1].to]) {
72             e[i].flow -= theMin;
73             e[i^1].flow += theMin;
74         }
75     }
76     return flow;
77 }
78 int main() {
79     while(~scanf("%d %d",&n,&k)) {
80         memset(head,-1,sizeof(head));
81         S = 0;
82         T = n-1;
83         int tmp;
84         for(int i = tot = 0; i < n; ++i)
85             for(int j = 0; j < n; ++j) {
86                 scanf("%d",&tmp);
87                 if(tmp) {
88                     add(i,j,tmp,0);
89                     add(i,j,k,1);
90                 }
91             }
92         printf("%d\n",solve());
93     }
94     return 0;
95 }

时间: 2024-08-07 01:58:15

CodeForces 362E Petya and Pipes的相关文章

Codeforces 362E Petya and Pipes 费用流建图

题意: 给一个网络中某些边增加容量,增加的总和最大为K,使得最大流最大. 费用流:在某条边增加单位流量的费用. 那么就可以2个点之间建2条边,第一条给定边(u,v,x,0)这条边费用为0 同时另一条边(u,v,K,1)费用为1,那么就可以通过限制在增广时相应的费用即可找出最大流 个人觉得这样做的原因是每次增光都是最优的.所以通过限制最终费用不超过K可以得到最优解 #include <map> #include <set> #include <list> #include

CodeForces 66C Petya and File System

模拟题,map搞一搞.用了点c11的特性. #include<bits/stdc++.h> using namespace std; typedef map<string,int> Node; map<string,int>::iterator it_id; const int maxnd = 1e4; Node nds[maxnd]; int nds_cnt; #define MP make_pair #define fi first #define se secon

CodeForces 362B Petya and Staircases

题意:一个小男孩要上楼梯,他一次可以走1个台阶或2个台阶或3个台阶,但是有一些台阶是脏的,他不想走在脏台阶上.一共有n个台阶和m个脏台阶,他最开始在第1个台阶上,要走到第n个台阶.问小男孩能不能不踩到脏台阶的前提下走到n个台阶. 思路:对于给定的m个脏序列,先排序后,没有连续的三个数就行. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #

CodeForces 112D Petya and Divisors 模拟题(水

题目链接:点击打开链接 论科学暴力的姿势重要性.. #include <cstdio> #include <iostream> #include <string.h> #include <math.h> #include <map> #include <algorithm> #include <set> #include <queue> using namespace std; #define ll int #

Codeforces 362E 费用流

题意及思路:https://blog.csdn.net/mengxiang000000/article/details/52472696 代码: #define Hello the_cruel_world! #pragma GCC optimize(2) #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<cstring> #inclu

CodeForce-797C Minimal string(贪心模拟)

Minimal string CodeForces - 797C Petya 收到一个长度不超过 105 的字符串 s.他拿了两个额外的空字符串 t 和 u 并决定玩一个游戏.这个游戏有两种合法操作: 将 s 串的第一个字符移动到字符串 t 的末尾. 将 t 串的最后一个字符移动到字符串 u 的末尾. Petya 希望将 s 和 t 都变为空串并且使得串 u 字典序最小. 你需要写一个代码求出最小的字典序. Input 第一行包含一个非空串 s (1?≤?|s|?≤?105),只包含小写字母.

Codeforces Round #319 (Div. 2) C Vasya and Petya&#39;s Game

因为所有整数都能被唯一分解,p1^a1*p2^a2*...*pi^ai,而一次询问的数可以分解为p1^a1k*p2^a2k*...*pi^aik,这次询问会把所有a1>=a1k && a2 >= a2k &&... a3 >= a3k的数从原来的集合中分开.ai表示pi的幂. 那么只有当这个数的素因子的最大幂都被询问过一次,这个数才能确定.因此答案是所有的不大于n的只有一个素因子的数. #include<bits/stdc++.h> using

CodeForces 577C Vasya and Petya&#39;s Game 数学

题意就是给你一个1到n的范围 你每次可以问这个数是否可以被某一个数整除 问你要猜多少数才能确定这个数…… 一开始一点思路也没有 后来查了一下才知道 每个数都可以分为几个质数的整数次幂相乘得到…… 1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 #include<string.h> 6 #include<string>

Codeforces Round #590 (Div. 3) C. Pipes

链接: https://codeforces.com/contest/1234/problem/C 题意: You are given a system of pipes. It consists of two rows, each row consists of n pipes. The top left pipe has the coordinates (1,1) and the bottom right - (2,n). There are six types of pipes: two