标签:
//给一个无向图, //一个人从起点到走到终点只走最短路 //问最少需要删除多少边使得其不能从起点走到终点 //问最多删除多少点使得其能走到终点 //先求出所有在最短路上的边,对这些边重建图 //将其权值改为1,那么其最大流就是其最小割 //刚开始没有考虑为无向图,坑了半天 #include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std ; const int maxn = 2010 ; const int maxm = 12e4+10 ; const int inf = 0x3f3f3f3f ; int head[maxn] , vis[maxn] ; int dis[maxn] ; int x[maxm] , y[maxm] , z[maxm] ; int sum[maxn] ; int len ;int nedge ; int n , m ; int st , en ; struct Edge { int v , w ; int next ; }edge[maxm<<1] ; void addedge(int u , int v ,int w) { edge[nedge].v = v; edge[nedge].w = w ; edge[nedge].next = head[u] ; head[u] = nedge++ ; } int spfa() { memset(vis , 0 ,sizeof(vis)) ; for(int i = 1;i <= n;i++) sum[i] = dis[i] = i == st ? 0 : inf ; queue<int>que; que.push(st) ; vis[st] = 1; while(que.size()) { int u = que.front();que.pop() ; vis[u] = 0 ; for(int i = head[u];i != -1 ;i = edge[i].next) { int v = edge[i].v ; if(edge[i].w && dis[u] + edge[i].w < dis[v]) { dis[v] = dis[u] + edge[i].w ; if(!vis[v]) { vis[v] = 1 ; que.push(v) ; } } } } return dis[en] ; } bool bfs() { queue<int> que ; memset(dis , -1 ,sizeof(dis)) ; dis[st] = 0 ; que.push(st) ; while(que.size()) { int u = que.front() ; que.pop() ; for(int i = head[u]; i != -1 ; i = edge[i].next) { int v = edge[i].v ; if(edge[i].w > 0 && dis[v] < 0) { dis[v] = dis[u] + 1 ; que.push(v) ; } } } if(dis[en] > 0) return true ; return false ; } int dfs(int x,int mx) { if(x==en) return mx; int i; int ans=0; int a; for(i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w)))) { edge[i].w -= a; edge[i^1].w += a; ans += a; mx -= a; if(!mx) break; } } if(!ans) dis[x] = -1; return ans; } int main() { // freopen("in.txt" , "r" , stdin) ; while(~scanf("%d%d" , &n , &m)) { memset(head , -1 , sizeof(head)) ; nedge = 0 ;len = 0 ; for(int i = 0;i < m;i++) { int u , v , w ; scanf("%d%d%d" , &u , &v , &w) ; addedge(u , v ,w) ; addedge(v , u , w) ; x[len] = u , y[len] = v ,z[len++] = w ; x[len] = v , y[len] = u ,z[len++] = w ; } st = 1 , en = n; int mi = spfa() ; if(mi == inf) { puts("0 0"); continue ; } memset(head , -1 , sizeof(head)) ; nedge = 0 ; for(int i = 0;i < len ;i++) if(dis[x[i]] + z[i] == dis[y[i]]) { addedge(x[i] , y[i] , 1) ; addedge(y[i] , x[i] , 0) ; } mi = spfa() ; int ans = 0 ,res ; while(bfs()) while(res = dfs(st , inf)) ans += res ; cout<<ans<<" "<<m - mi<<endl; } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/cq_pf/article/details/47704221