HDU6214 Smallest Minimum Cut 最小割/最少边 [2017 ACM/ICPC Asia Regional Qingdao Online]

来源:互联网 发布:阿里云控制平台 编辑:程序博客网 时间:2024/06/05 02:07

题目链接

Problem Description

Consider a network G=(V,E) with source s and sink t. An s-t cut is a partition of nodes set V into two parts such that s and t belong to different parts. The cut set is the subset of E with all edges connecting nodes in different parts. A minimum cut is the one whose cut set has the minimum summation of capacities. The size of a cut is the number of edges in the cut set. Please calculate the smallest size of all minimum cuts.

Input

The input contains several test cases and the first line is the total number of cases T (1≤T≤300).
Each case describes a network G, and the first line contains two integers n (2≤n≤200) and m (0≤m≤1000) indicating the sizes of nodes and edges. All nodes in the network are labelled from 1 to n.
The second line contains two different integers s and t (1≤s,t≤n) corresponding to the source and sink.
Each of the next m lines contains three integers u,v and w (1≤w≤255) describing a directed edge from node u to v with capacity w.

Output

For each test case, output the smallest size of all minimum cuts in a line.

Sample Input

2
4 5
1 4
1 2 3
1 3 1
2 3 1
2 4 1
3 4 2
4 5
1 4
1 2 3
1 3 1
2 3 1
2 4 1
3 4 3

Sample Output

2
3


方案一:先跑一边最大流,如果边满流,容量+1;否者,容量inf。再跑一遍最大流或者先跑一边最大流,如果边满流,容量置1,流量置0;否者,容量置inf。再跑一遍最大流

方案二:对容量进行处理,容量*(大数或者边数M+1)+1,跑一边最大流Maxflow,处理前的最大流为Maxflow/(M+1),最少边数的最小割集为Maxflow%(M+1)。说明:原图的最小割为为x1、x2、x3...,即∑x,处理后的最小割为∑x*(M+1)+B,其中B为原图最小割边的数量,如果能有边数更少的情况,处理后最小割也会相应的减少,所以处理后得到的B即为最少边数。

方案1

#include<bits/stdc++.h>#define MAXN 1010#define MAXM 400000+10#define INF 0x3f3f3f3fusing namespace std;struct Edge{    int from, to, cap, flow, next;};Edge edge[MAXM];int head[MAXN], cur[MAXN], edgenum;int dist[MAXN];bool vis[MAXN];int N, M,ss,tt;void init(){    edgenum = 0;    memset(head, -1, sizeof(head));}void addEdge(int u, int v, int w){    Edge E1 = {u, v, w, 0, head[u]};    edge[edgenum] = E1;    head[u] = edgenum++;    Edge E2 = {v, u, 0, 0, head[v]};    edge[edgenum] = E2;    head[v] = edgenum++;}bool BFS(int s, int t){    queue<int> Q;    memset(dist, -1, sizeof(dist));    memset(vis, false, sizeof(vis));    dist[s] = 0;    vis[s] = true;    Q.push(s);    while(!Q.empty())    {        int u = Q.front();        Q.pop();        for(int i = head[u]; i != -1; i = edge[i].next)        {            Edge E = edge[i];            if(!vis[E.to] && E.cap > E.flow)            {                dist[E.to] = dist[u] + 1;                if(E.to == t) return true;                vis[E.to] = true;                Q.push(E.to);            }        }    }    return false;}int DFS(int x, int a, int t){    if(x == t || a == 0) return a;    int flow = 0, f;    for(int &i = cur[x]; i != -1; i = edge[i].next)    {        Edge &E = edge[i];        if(dist[E.to] == dist[x] + 1 && (f = DFS(E.to, min(a, E.cap - E.flow), t)) > 0)        {            edge[i].flow += f;            edge[i^1].flow -= f;            flow += f;            a -= f;            if(a == 0) break;        }    }    return flow;}int Maxflow(int s, int t){    int flow = 0;    while(BFS(s, t))    {        memcpy(cur, head, sizeof(head));        flow += DFS(s, INF, t);    }    return flow;}void solve(){    Maxflow(ss, tt);    for(int i = 0; i < edgenum; i+=2)    {        Edge E = edge[i];        if(E.cap == E.flow)        {            edge[i].cap =1;            edge[i].flow = 0;        }        else        {            edge[i].cap = INF;            edge[i].flow = 0;        }//        edge[i^1].cap = edge[i^1].flow = 0;    }    printf("%d\n",  Maxflow(ss, tt));}int T;int main(){//    freopen("data.txt","r",stdin);    scanf("%d", &T);    while(T--)    {        scanf("%d%d", &N, &M);        scanf("%d%d",&ss,&tt);        ss--;        tt--;        init();        int u1,v1,w1;        while(M--)        {            scanf("%d%d%d", &u1,&v1,&w1);            u1--;            v1--;            addEdge(u1, v1, w1);        }        solve();    }    return 0;}

方案2

#include<bits/stdc++.h>#define MAXN 410#define MAXM 9000+10#define INF 0x3f3f3f3fusing namespace std;struct Edge{    int from, to, cap, flow, next;};Edge edge[MAXM];int head[MAXN], cur[MAXN], edgenum;int dist[MAXN];bool vis[MAXN];int N, M,ss,tt;void init(){    edgenum = 0;    memset(head, -1, sizeof(head));}void addEdge(int u, int v, int w){    Edge E1 = {u, v, w, 0, head[u]};    edge[edgenum] = E1;    head[u] = edgenum++;    Edge E2 = {v, u, 0, 0, head[v]};    edge[edgenum] = E2;    head[v] = edgenum++;}bool BFS(int s, int t){    queue<int> Q;    memset(dist, -1, sizeof(dist));    memset(vis, false, sizeof(vis));    dist[s] = 0;    vis[s] = true;    Q.push(s);    while(!Q.empty())    {        int u = Q.front();        Q.pop();        for(int i = head[u]; i != -1; i = edge[i].next)        {            Edge E = edge[i];            if(!vis[E.to] && E.cap > E.flow)            {                dist[E.to] = dist[u] + 1;                if(E.to == t) return true;                vis[E.to] = true;                Q.push(E.to);            }        }    }    return false;}int DFS(int x, int a, int t){    if(x == t || a == 0) return a;    int flow = 0, f;    for(int &i = cur[x]; i != -1; i = edge[i].next)    {        Edge &E = edge[i];        if(dist[E.to] == dist[x] + 1 && (f = DFS(E.to, min(a, E.cap - E.flow), t)) > 0)        {            edge[i].flow += f;            edge[i^1].flow -= f;            flow += f;            a -= f;            if(a == 0) break;        }    }    return flow;}int Maxflow(int s, int t){    int flow = 0;    while(BFS(s, t))    {        memcpy(cur, head, sizeof(head));        flow += DFS(s, INF, t);    }    return flow;}void solve(){//    Maxflow(ss, tt);////    for(int i = 0; i < edgenum; i+=2)//    {//        Edge E = edge[i];//        if(E.cap == E.flow)//        {//            edge[i].cap = 1;//            edge[i].flow = 0;//        }//        else//        {//            edge[i].cap = INF;//            edge[i].flow = 0;//        }//        edge[i^1].cap = edge[i^1].flow = 0;//    }    printf("%d\n",  Maxflow(ss, tt)%10000);}int T;int main(){//    freopen("data.txt","r",stdin);    scanf("%d", &T);    while(T--)    {        scanf("%d%d", &N, &M);        scanf("%d%d",&ss,&tt);        init();        int u,v,w;        while(M--)        {            scanf("%d%d%d", &u,&v,&w);            addEdge(u, v, w*10000+1);        }        solve();    }    return 0;}bian
阅读全文
0 0
原创粉丝点击