最大流Dinic
最近被济南打自闭了,要学习一波图论和数学方面的知识了
推荐一波大佬的知乎
一道模板题
洛谷p1343
将人看成流量
所以每次最多的人数就相当于求一次最大流就OK了
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = INT_MAX;
struct Edge{
int to, c;
int next;
Edge(){
to = 0;
c = 0;
next = 0;
};
};
const int MAXN= 1e4+10;
const int N = 205;
Edge edges[MAXN];
int head[N];
int cnt =1;
void add(int from, int to, int c){
cnt += 1;
edges[cnt].to = to;
edges[cnt].next = head[from];
edges[cnt].c = c;
head[from] = cnt;
}
int s,t;
int n,m;
int level[N], cur[N];
bool bfs(){ //当前的图进行分层
memcpy(cur, head, sizeof head);
memset(level, -1, sizeof level);
level[s]=0;
queue<int> que;
que.push(s);
while(!que.empty()){
int p = que.front();
que.pop();
for(int eg=head[p]; eg; eg=edges[eg].next){
int to = edges[eg].to, c = edges[eg].c;
if(c && level[to]==-1)
level[to]=level[p]+1, que.push(to);
}
}
return level[t]!=-1;
}
int dfs(int p=s, int flow = INF){
if(p==t)
return flow;
int rem = flow;
for(int eg = cur[p]; eg&&rem; eg = edges[eg].next){
cur[p]=eg; //被增广过的边不会再被增广,因为分层之后尽量使用的
int to = edges[eg].to, c = edges[eg].c;
if(c && level[to]==level[p]+1){ //往下一层增广
int c_flow = dfs(to, min(c, rem)); //管道内的较小的被限制
rem -= c_flow;
edges[eg].c -= c_flow;
edges[eg^1].c += c_flow;
}
}
return flow - rem;//增广掉的流量就是流
}
ll dinic(){
ll ans = 0;
while(bfs()){
ans += dfs();
}
return ans;
}
int main(){
// freopen("in.dat", "r", stdin);
memset(head, 0, sizeof head);
int x;
cin>>n>>m>>x;
s = 1;
t = n;
int from, to, c;
for(int i=0; i<m; i++){
cin>>from>>to>>c;
add(from, to, c);
add(to, from, 0);
}
ll ans = dinic();
if(ans==0){
cout<<"Orz Ni Jinan Saint Cow!"<<endl;
return 0;
}
cout<<ans<<" "<<(x/ans + (x%ans!=0))<<endl;
return 0;
}
一条有梦想的咸鱼