1. 程式人生 > >HDU 6214 Smallest Minimum Cut (最小割最小割邊)(兩種演算法的分析)

HDU 6214 Smallest Minimum Cut (最小割最小割邊)(兩種演算法的分析)

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

Source
2017 ACM/ICPC Asia Regional Qingdao Online

無語自己,比賽結束一打程式碼就過了,裸的最小割最小割邊
這裡寫圖片描述

用的第一種,比賽時用第二種一直超時和WA,哎!
對於第一種演算法:
最小割最小割邊的 建邊的時候每條邊權 w = w * (E + 1) + 1; //加上1之後跑出來的最大流必定是變數最小的。
這樣得到的最大流為max_flow/(E+1),因為即使所以的邊都算上,也只是多個E,那麼除以(E+1)是完全不影響的,而最小的割邊數是max_flow % (E+1) 即把全部的1
算上也只有E,對E+1取餘後就是最小的變數

而第二種演算法,可以過HDU3987 但其實是一種錯誤的演算法,在有些情況時跑出來的不是最小邊,如下圖,某位大神給我找到的反例,這個圖就可以搞掉第二種演算法,不過如果是用鏈式前向星存圖的話,可能是走1000那條邊的,就再修改一下:
這裡寫圖片描述
紅線代表滿流邊,如果按照第二種演算法的話得到的是2,而實際是4.

#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<string>
#include<queue>
#include<algorithm>

using namespace std;
const int MAX_V = 210;
const int MAX_E = 3010;
const int INF = 0x3f3f3f3f;

int V,E;
struct Edge{
    int to,cap,rev;
};
vector<Edge> G[MAX_V];
int level[MAX_V],iter[MAX_V];

void add(int u,int v,int cap){
    G[u].push_back((Edge){v,cap*(E+1)+1,(int)G[v].size()});
    G[v].push_back((Edge){u,0,(int)G[u].size()-1});
}

void bfs(int s){
    memset(level,-1,sizeof(level));
    queue<int> q;
    level[s] = 0;
    q.push(s);
    while(!q.empty()){
        int v = q.front();q.pop();
        for(int i=0;i<G[v].size();i++){
            Edge &e = G[v][i];
            if(e.cap > 0 && level[e.to] < 0){
                level[e.to] = level[v] + 1;
                q.push(e.to);
            }
        }
    }
}

int dfs(int s,int t,int f){
    if(s == t)  return f;
    for(int &i = iter[s];i < G[s].size();i++){
        Edge &e = G[s][i];
        if(e.cap > 0 && level[s] < level[e.to]){
            int d = dfs(e.to,t,min(e.cap,f));
            if(d > 0){
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

int max_flow(int s,int t){
    int res = 0;
    while(true){
        bfs(s);
        if(level[t] < 0)    return res;
        memset(iter,0,sizeof(iter));
        int f = 0;
        while((f = dfs(s,t,INF)) > 0)
            res += f;
    }
}
int main(void){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&V,&E);
        for(int i=1;i<=V;i++)
            G[i].clear();
        int a,b;
        scanf("%d %d",&a,&b);
        int x,y,z;
        for(int i=1;i<=E;i++){
            scanf("%d %d %d",&x,&y,&z);
            add(x,y,z);
        }
        int res = max_flow(a,b);
        printf("%d\n",res % (E+1));
    }


    return 0;
}

相關推薦

HDU 6214 Smallest Minimum Cut 2017青島網賽1009()

target app left shu info lis 最小 get qt5 j99r2xn磊乩叛8http://jz.docin.com/crv79826 B烈04lN186u氨事28http://shufang.docin.com/xei31846 GzD93Co

HDU 6214 Smallest Minimum Cut ()演算法分析

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 s

hdu 6214 Smallest Minimum Cut[大流]

get spl clu oid closed logs color cto 最大 hdu 6214 Smallest Minimum Cut[最大流] 題意:求最小割中最少的邊數。 題解:對邊權乘個比邊大點的數比如300,再加1 ,最後,最大流對300取余就是邊數啦。。

6214 Smallest Minimum Cut 求最少數的

Time limit 2000 ms ,Memory limit 32768 kB Consider a network G=(V,E) with source s and sink t. An s-t cut is a partition of nodes set V i

短路和差分約束演算法實現 Til the Cows Come Home

題目訓練連結(密碼hpuacm): https://vjudge.net/contest/246705 我會分別用 迪傑斯特拉  優先佇列和鏈式前向星優化過的迪傑斯特拉  SPFA演算法 三種方法講一下例題。 此外上述三種演算法是求單源最短路問題, 這裡還會

凸多邊形優三角剖分的演算法分析

/* Name: Copyright: Author: 巧若拙 Date: 27-03-17 10:11 Description: 動態規劃--凸多邊形最優三角剖分 題目描述: 用多邊形頂點的逆時針序列表示凸多邊形,即P={v0,v1,…,vn

2017青島賽區網絡賽 Smallest Minimum Cut

ext size 完整 bool minimum nbsp 網絡賽 else include 先最大流跑一遍 在殘存網絡上把滿流邊容量+1 非滿流邊容量設為無窮大 在進行一次最大流即可 (這裏的邊都不包括建圖時用於反悔的反向邊) 1 #include<cstdi

HDU6214 Smallest Minimum Cut大流求

傳送門 因為最大流=最小割邊的最大流量限制之和 因為m<=1000 將每條邊流量*2000+1 不難發現 假如原圖有2個最小割,大小分別為x,y(x < y) 改流量後只有x能流滿 跑出來的最大流%2000=最小割邊數量 #incl

樹形圖朱劉演算法模板

求有固定根的最小樹形圖的演算法 演算法步驟: (1)求最短弧集:除了根節點外,找到所有其他的節點最小邊權的入邊(用in陣列記錄到達改點的最小邊權,用pre陣列記錄其父節點) (2)檢驗生成的集合中是否

CSS3實現五子棋Web遊戲,Canvas畫布和DOM實現,並且具有悔棋和撤銷悔棋功能。

posit oct padding 角色 sar pac osi fse ech 用Canvas實現五子棋的思路: 1、點擊棋盤,獲取坐標x,y,計算出棋子的二維數組坐標i和j, 2、棋子的實現,先arc一個圓,再填充漸變色。 3、下完一步棋後切換畫筆和角色。 4、贏法算法

微信程序--跳轉頁面常用的方法

avi mage site product 小程序 src bsp XML 兩種 一.bindtap="onProductsItemTap"綁定點擊跳轉事件 在.wxml文件中綁定 在.js文件中實現綁定事件函數 二.navigator標簽配合URL跳轉

bzoj1022: [SHOI2008]約翰的遊戲John博弈SG-nim遊戲

mat flag enter int ans problem blank 入門題 pos 1022: [SHOI2008]小約翰的遊戲John 題目:傳送門 題目大意:    一道反nim遊戲,即給出n堆石子,每次可以取完任意一堆或一堆中的若幹個(至少取1),最後一

白學英語--發音篇元子音口訣表

元子音口訣表: 這個口訣表通過熟練掌握元子音口訣表和後期一些變音方法,我們基本就可以看到單詞就可以讀出他的準確發音,在這裡英語中的元子音發音會與漢語拼音發音不同,在這裡我們只用英文拼音發音,不要混淆。為了方便大家能看到字母就可以發音,在這裡我在括號中用漢語拼音來註釋,後面用漢字來描述。 發音

長上升子序列方法

常規方法:(n^2) #include<iostream> using namespace std; int i,j,n,a[100],b[100],max; int main() { cin>>n; for(i=0;i<n;i++)

短路的另外演算法

//由於Dijksrta演算法,當圖中的權值邊含有負值時,求不出最短路 //原因是因為,每個結點只能入隊一次,被訪問過後永久標記,所以,當存在一條負的權值邊 //使得某一個節點到源點s的距離更短時,無法再一次呼叫此結點更新其餘的點 //所以下面介紹另外的兩種演算法 //Bellman-Ford演算法:如

[UOJ#340][清華集訓2017] Y 和恐怖的奴隸主期望 DP + 矩陣乘法

Address 洛谷P4007 UOJ#340 LOJ#2325 Solution 難道 m m

大流EK、Dinic、SAP三演算法模板

EK   //Max_flow //@2018/05/02 Wednesday //EK algorithm [Edmonds Karp] O(V*E^2) O(v^2) //by Tawn #include <bits/stdc++.h> using nam

演算法】topK問題:得到序列中前k的數含複雜度分析

思路一 利用排序方法(快排/堆排序)對序列從小到大進行排序 輸出序列前k個數  void TopK( int a[], int n, int k ) { if(k<0 || k>n) return;    sort(a,n);

短路問題演算法與路徑還原演算法

1、Bellman-Ford演算法: 用Bellman-Ford演算法求解單源最短路徑問題,單源最短路徑是指固定一個起點,求它到其他所有點的最短路問題。 struct edge { int from, to, cost; //從頂點from指向頂點to的權值為c

leetcode53:求解大子序和方法

演算法思路和演算法複雜度分析在函式中 public class leetcode_53 { /** * 最大子序列和 * * */ public static void main(String[] args) { //測試第一種