HDU 6214 Smallest Minimum Cut 2017青岛网赛1009(最小割最小割边)

来源:互联网 发布:windows怎么读音发音 编辑:程序博客网 时间:2024/05/29 16:19


Smallest Minimum Cut

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3297    Accepted Submission(s): 602


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 (1T300).
Each case describes a network G, and the first line contains two integers n (2n200) and m (0m1000) 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 (1s,tn) corresponding to the source and sink.
Each of the next m lines contains three integers u,v and w (1w255) 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
24 51 41 2 31 3 12 3 12 4 13 4 24 51 41 2 31 3 12 3 12 4 13 4 3
 

Sample Output
23
 

Source
输入输出测试
 

Statistic | Submit | Clarifications | Back

建边的时候每条边权 w = w * (E + 1) + 1;
这样得到最大流 maxflow / (E + 1) ,最少割边数 maxflow % (E + 1)

道理很简单,如果原先两类割边都是最小割,那么求出的最大流相等
但边权变换后只有边数小的才是最小割了

乘(E+1)是为了保证边数叠加后依然是余数,不至于影响求最小割的结果

因为假设最小割=k,那么现在新图的最小割为k*(E+1)+p,p为割的边数,本质上是,原来你割一条边,需要代价,

由于你要求边数最小 所以你多割一条边,就多一的代价,但是这个代价不足以影响到原来的代价。
原来割一条边,代价xi,现在割一条边,代价xi*A+1,只要让A>m+1,m为边数,即使割了所有的边,自己加上去的代价也就m

至于跑两次Dinic(), 是不对的, 其实很简单, 最小割一定是满流, 但是满流的不一定是最小割。。。

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <queue>using namespace std;const int INF = 1e9;const int maxn = 1e3 + 7;const int maxv = 2e4 + 5;int head[maxv], cur[maxv], d[maxv], s, t, k, k1, sum, book[maxn];int n, m;void init(){    k = 0;    memset(head, -1, sizeof(head));}struct node{    int v, w, next;}edge[maxv];void addEdge(int u, int v, int w){    edge[k].v = v;    edge[k].w = w;    edge[k].next = head[u];    head[u] = k++;    edge[k].v = u;    edge[k].w = 0;    edge[k].next = head[v];    head[v] = k++;}int Q[maxv];int bfs(){    memset(d, 0, sizeof(d));    d[s] = 1;    int frnt = 0, rear = 0;    Q[rear++] = s;    while(frnt != rear)    {        int u = Q[frnt++];        if(u == t) return 1;        for(int i = head[u]; i != -1; i = edge[i].next)        {            int to = edge[i].v, w = edge[i].w;            if(w && d[to] == 0)            {                d[to] = d[u] + 1;                if(to == t) return 1;                Q[rear++] = to;            }        }    }    return 0;}int dfs(int u, int maxflow){    if(u == t || !maxflow) return maxflow;    int ret = 0;    for(int& i = cur[u]; i != -1; i = edge[i].next)    {        int to = edge[i].v, w = edge[i].w;        if(w && d[to] == d[u]+1)        {            int f = dfs(to, min(maxflow-ret, w));            edge[i].w -= f;            edge[i^1].w += f;            ret += f;            if(ret == maxflow) return ret;        }    }    return ret;}int Dinic(){    int ans = 0;    while(bfs() == 1)    {        memcpy(cur, head, sizeof(head));        ans += dfs(s, INF);    }    return ans;}int main(){    int _;    scanf("%d", &_);    while(_--)    {        int x, y, z;        init();        scanf("%d%d", &n, &m);        scanf("%d%d", &s, &t);        for(int i = 0; i < m; i++)        {            scanf("%d%d%d", &x, &y, &z);            addEdge(x, y, z*(m+1)+1);        }//        Dinic();//        for(int i = 0;i < k; i += 2)//        {//            if(edge[i].w == 0)//            {//                edge[i].w = 1;//                edge[i^1].w = 0;//            }//            else//            {//                edge[i].w = INF;//                edge[i^1].w = 0;//            }//        }        printf("%d\n", Dinic()%(m+1));    }    return 0;}


阅读全文
0 0
原创粉丝点击