题解 P1343 【地震逃生】
abandentsky · · 题解
题意:就不说了,说来说去就是给定一个有向图,把权值视为容量,然后跑一边最大流得到最小割。完了就可以计算了,如果最大流为0,就是不能完成输出“Orz Ni Jinan Saint Cow!”,如果不是0就要考虑能不能整除,不能整除就要在商上加上一。
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define MAXN 205
#define maxnode 1000005
#define sigma_size 26
#define md 12345678
#define INF 0x3f3f3f3f
#define pii pair<int,int>
using namespace std;
struct Edge
{
int from,to,cap,flow;
Edge(int from=0,int to=0,int cap=0,int flow=0):from(from),to(to),cap(cap),flow(flow){};
};
int n,m,s,t,k;
struct Dinic
{
int n,m,s,t;
bool vis[MAXN];
int d[MAXN],cur[MAXN];
vector<Edge> edges;
vector<int> G[MAXN];
void init(int n)
{
this->n=n;
edges.clear();
for(int i=0;i<=n;i++)
G[i].clear();
}
void AddEdge(int from,int to,int cap)
{
edges.push_back({from,to,cap,0});
edges.push_back({to,from,0,0});
int mm=edges.size();
G[from].push_back(mm-2);
G[to].push_back(mm-1);
}
bool bfs()
{
memset(vis,0,sizeof(vis));
d[s]=0,vis[s]=true;
queue<int> Q;
Q.push(s);
while(!Q.empty())
{
int X=Q.front();
Q.pop();
for(int i=0;i<G[X].size();i++)
{
Edge &e=edges[G[X][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to]=true;
d[e.to]=d[X]+1;
Q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x,int a)
{
if(x==t||a==0)
return a;
int flow=0;
int f;
for(int &i=cur[x];i<G[x].size();i++)
{
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
{
flow+=f;
e.flow+=f;
edges[G[x][i]^1].flow-=f;
a-=f;
if(a==0)
break;
}
}
return flow;
}
int Maxflow(int s,int t)
{
this->s=s;
this->t=t;
int flow=0;
while(bfs())
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}dinic;
int main()
{
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
dinic.AddEdge(u,v,w);
}
int ans=dinic.Maxflow(1,n);
if(ans==0)
{
printf("Orz Ni Jinan Saint Cow!\n");
return 0;
}
int sum=k/ans;
if(k%ans)
sum+=1;
printf("%d %d\n",ans,sum);
return 0;
}