題意是要找最少斷有幾條路能使無邪抓不到寧,最多斷幾條路還能抓到,首先是求最短路中最小步數cnt,用(總路數-cnt)即最多的,然後再在所有最短路的基礎上找邊權爲1的最大流,原因就是到達終點的最短路即使不同,但也有可能經過同一條路到達終點,而最大流則可以求出最短路中終點的最大入度。
#include <bits/stdc++.h>
using namespace std;
const int M=60005;
const int N=20005;
const int INF=0x7fffffff;
struct edge{
int to,cost;
int rev;
}e[N];
vector<edge>mp[N];
vector<pair<int,int> >G[N];
int n,m;
int dist[M];
int used[M];
int cnt[M];
int nod[M];
int level[M];
int iter[M];
bool vis[M];
queue<int>q;
void spfa(int s,int t){ //spfa算法最短路
memset(used,0,sizeof used);
memset(dist,127,sizeof dist);
memset(cnt,127,sizeof cnt);
dist[s]=0;
used[s]=1;
cnt[s]=0;
while(!q.empty()) q.pop();
q.push(s);
while(!q.empty()){
int v=q.front();
q.pop();
used[v]=0;
for(int i=0;i<G[v].size();i++){
int u=G[v][i].first;
int c=G[v][i].second;
if(dist[u]==dist[v]+c) //計算最小步數
cnt[u]=min(cnt[v]+1,cnt[u]);
if(dist[u]>dist[v]+c){
dist[u]=dist[v]+c;
cnt[u]=cnt[v]+1;
if(!used[u]){ //由於會有重邊
used[u]=1;
q.push(u);
}
}
}
}
}
bool bfs(){ //最大流中求最短增廣路
int s=1,t=n;
queue<int>qq;
memset(vis,false,sizeof vis);
memset(level,-1,sizeof level);
level[s]=0;
vis[s]=true;
qq.push(s);
while(!qq.empty()){
int u =qq.front();
qq.pop();
vis[u]=false;
for(int i=0;i<mp[u].size();i++){
edge &ee=mp[u][i];
if(ee.cost>0 && level[ee.to]<0&&!vis[ee.to]){
vis[ee.to]=true;
level[ee.to]=level[u]+1;
if(ee.to==t) return true;
qq.push(ee.to);
}
}
}
return false;
}
void add(int u,int v){ //添加最短路重新構成圖
mp[u].push_back((edge){v,1,mp[v].size()});
mp[v].push_back((edge){u,0,mp[u].size()-1});
}
void build() //建圖
{
for(int i= 1;i<=n;i++)
mp[i].clear();
for(int i=1;i<=n;i++){
for(int j=0;j<G[i].size();j++){
int u=G[i][j].first;
int c=G[i][j].second;
if(dist[u]==dist[i]+c){
add(i,u);
}
}
}
/*for(int i=1;i<=n;i++){
for(int j=0;j<mp[i].size();j++)
cout<<i<<" "<<mp[i][j].to<<" "<<mp[i][j].cost<<" "<<mp[i][j].rev<<endl;
}*/
}
int dfs(int v,int t,int f){ //求一條增廣路上的最大流
if(v==t||f==0) return f;
for(int i=0;i <mp[v].size();i++){
edge &ee=mp[v][i];
if(ee.cost>0 && level[ee.to]>level[v]){
int d=dfs(ee.to,t,min(f,ee.cost));
if(d>0){
ee.cost-=d;
mp[ee.to][ee.rev].cost+=d;
return d;
}
}
}
return 0;
}
int max_flow(){ //dinic算法求最大流
int flow=0;
memset(vis,false,sizeof vis);
// memset(iter,0,sizeof iter);
while(bfs()){ //還有增廣路
if(level[n]<0) break;
// memset(iter,0,sizeof iter);
int f=dfs(1,n,INF);
flow+=f; //總的流
}
return flow;
}
int main()
{
while(scanf("%d%d",&n,&m)!=-1){
for(int i=1;i<=n;i++)
G[i].clear();
memset(cnt,0,sizeof cnt);
for(int i=0;i<m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
G[x].push_back(make_pair(y,z));
G[y].push_back(make_pair(x,z));
}
spfa(1,n);
build();
int ans=max_flow();
cout<<ans<<" ";
cout<<m-cnt[n]<<endl;
}
return 0;
}