icontofig | 发布于 2019-02-14 10:43:38 | 阅读量 326 | 网络流 最小割 最短路

## Description

Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu’s at the entrance of the tomb while Dumb Zhang’s at the end of it. The tomb is made up of many chambers, the total number is N. And there are M channels connecting the chambers. Innocent Wu wants to catch up Dumb Zhang to find out the answers of some questions, however, it’s Dumb Zhang’s intention to keep Innocent Wu in the dark, to do which he has to stop Innocent Wu from getting him. Only via the original shortest ways from the entrance to the end of the tomb costs the minimum time, and that’s the only chance Innocent Wu can catch Dumb Zhang.
Unfortunately, Dumb Zhang masters the art of becoming invisible(奇门遁甲) and tricks devices of this tomb, he can cut off the connections between chambers by using them. Dumb Zhang wanders how many channels at least he has to cut to stop Innocent Wu. And Innocent Wu wants to know after how many channels at most Dumb Zhang cut off Innocent Wu still has the chance to catch Dumb Zhang.

## Input

There are multiple test cases. Please process till EOF.
For each case,the first line must includes two integers, N(<=2000), M(<=60000). N is the total number of the chambers, M is the total number of the channels.
In the following M lines, every line must includes three numbers, and use ai、bi、li as channel i connecting chamber ai and bi(1<=ai,bi<=n), it costs li(0<li<=100) minute to pass channel i.
The entrance of the tomb is at the chamber one, the end of tomb is at the chamber N.

## Output

Output two numbers to stand for the answers of Dumb Zhang and Innocent Wu’s questions.

```8 9
1 2 2
2 3 2
2 4 1
3 5 3
4 5 4
5 8 1
1 6 2
6 7 5
7 8 1```

`2 6`

## 代码

```#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2005;
const int maxm = 6e4+5;
int get_num(){
int num = 0;
char c;
bool flag = false;
while((c = getchar()) == ' ' || c == '\r' || c == '\n');
if(c == '-')
flag = true;
else num = c - '0';
while(isdigit(c = getchar()))
num = (((num<<2)+num)<<1) + c - '0';
return (flag ? -1 : 1) * num;
}
struct edge{
int to,next,d;
}ed[maxm<<1];
int h[maxn];
struct flow_di{
int fr,to,next,cap;
}e[maxm<<2];
const int INF = 1e9+7;
int g[maxn];
int dis[maxn],dis2[maxn],vis[maxn],cur[maxn];
int num,cnt;
int n,m;
int s,t;
void init(){
memset(ed,0,sizeof(ed));
memset(e,0,sizeof(e));
memset(h,-1,sizeof(h));
memset(g,-1,sizeof(g));
num = cnt = 0;
return;
}
ed[num].to = v;ed[num].next = h[u];ed[num].d = dis;
h[u] = num++;
return;
}
e[cnt].fr = u;e[cnt].to = v;e[cnt].cap = c;
e[cnt].next = g[u];g[u] = cnt++;
e[cnt].fr = v;e[cnt].to = u;e[cnt].cap = 0;
e[cnt].next = g[v];g[v] = cnt++;
return;
}
int ans = 0;
void spfa(int s){
queueq;
for(int i = 1;i <= n;++i)
dis[i] = INF,vis[i] = 0;
vis[s] = 1;
q.push(s);
dis[s] = 0;
while(!q.empty()){
int x = q.front();
q.pop();
vis[x] = 0;
for(int i = h[x];i != -1;i = ed[i].next){
int v = ed[i].to;
if(dis[v] > dis[x] + ed[i].d){
dis[v] = dis[x] + ed[i].d;
if(!vis[v]){
vis[v] = 1;
q.push(v);
}
}
}
}
return;
}
void spfa2(int s){
queueq;
for(int i = 1;i <= n;++i)
dis[i] = INF,vis[i] = 0;
vis[s] = 1;
q.push(s);
dis[s] = 0;
while(!q.empty()){
int x = q.front();
q.pop();
vis[x] = 0;
for(int i = g[x];i != -1;i = e[i].next){
int v = e[i].to;
if(dis[v] > dis[x] + 1){
dis[v] = dis[x] + 1;
if(!vis[v]){
vis[v] = 1;
q.push(v);
}
}
}
}
return;
}
bool BFS(int s,int t){
queueq;
for(int i = s;i <= t;++i)
dis2[i] = -1,vis[i] = 0;
vis[s] = 1;
dis2[s] = 0;
q.push(s);
while(!q.empty()){
int x = q.front();
q.pop();
for(int i = g[x];i != -1;i = e[i].next){
if(!vis[e[i].to] && e[i].cap > 0){
dis2[e[i].to] = dis2[x] + 1;
q.push(e[i].to);
vis[e[i].to] = 1;
}
}
}
return (dis2[t] != -1);
}
int DFS(int x,int a){
if(x == t || a == 0)return a;
int flow = 0,f;
for(int &i = cur[x];i != -1;i = e[i].next){
if(dis2[x] + 1 == dis2[e[i].to]){
f = min(e[i].cap,a - flow);
f = DFS(e[i].to,f);
flow += f;
e[i].cap -= f;
e[i^1].cap += f;
}
}
return flow;
}
int dinic_flow(int s,int t){
int flow = 0;
while(BFS(s,t)){
for(int i = 1;i <= n;++i)cur[i] = g[i];
flow += DFS(s,INF);
}
return flow;
}
int u,v,l;
int main(){
s = 1;
while(scanf("%d%d",&n,&m) != EOF){
init();
for(int i = 1;i <= m;++i){
u = get_num();
v = get_num();
l = get_num();
}
spfa(1);
for(int i = 1;i <= n;++i)
for(int j = h[i];j != -1;j = ed[j].next){
if(dis[i] + ed[j].d == dis[ed[j].to])
}
spfa2(1);
t = n;
int ans = dinic_flow(s,t),ans2 = m - dis[t];
printf("%d %d\n",ans,ans2);
}
return 0;
}﻿​```

326 人读过

0 条评论