hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割

view code//hdu 3987
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const ll INF = 1LL<<59;
const ll E = 100001;
const int N = 1010;
int _, n, m, pre[N], cur[N], d[N], s, t;
bool vis[N];

struct edge
{
    int u, v;
    ll cap, flow;
    int next;
    edge() {}
    edge(int u, int v, ll w, ll f, int p):u(u),v(v),cap(w),flow(f),next(p) {}
}e[N*400];
int ecnt;

void addedge(int u, int v, int w)
{
    e[ecnt] = edge(u, v, w*E+1, 0, pre[u]);
    pre[u] = ecnt++;
    e[ecnt] = edge(v, u, 0, 0, pre[v]);
    pre[v] = ecnt++;
}

bool BFS()
{
    memset(vis, 0, sizeof(vis));
    queue<int >q;
    q.push(s);
    d[s] = 0;
    vis[s] = 1;
    while(!q.empty())
    {
        int x = q.front(); q.pop();
        for(int i=pre[x]; ~i; i = e[i].next)
        {
            int v =e[i].v;
            if(!vis[v] && e[i].cap>e[i].flow)
            {
                d[v] = d[x] + 1;
                vis[v] = 1;
                q.push(v);
            }
        }
    }
    return vis[t];
}

ll DFS(int x, ll c)
{
    if(x==t || c==0) return c;
    ll flow = 0, f;
    for(int &i = cur[x]; ~i; i=e[i].next)
    {
        int v = e[i].v;
        if(d[x] + 1 == d[v] && (f=DFS(v, min(c, e[i].cap-e[i].flow)))>0)
        {
            e[i].flow += f;
            e[i^1].flow -= f;
            flow += f;
            c -= f;
            if(c==0) break;
        }
    }
    return flow;
}

ll Maxflow()
{
    s = 0, t = n-1;
    ll flow = 0;
    while(BFS())
    {
         for(int i=s; i<=t; i++) cur[i] = pre[i];
         flow += DFS(s, INF);
    }
    return flow;
}

void solve()
{
    scanf("%d%d", &n, &m);
    int u, v, w, flag;
    memset(pre, -1, sizeof(pre));
    ecnt = 0;
    for(int i=0; i<m; i++)
    {
        scanf("%d%d%d%d", &u, &v, &w, &flag);
        addedge(u, v, w);
        if(flag) addedge(v, u, w);
    }
    static int cas=1;
    printf("Case %d: ", cas++);
    cout<<Maxflow()%E<<endl;
}

int main()
{
//    freopen("in.txt", "r", stdin);
    cin>>_;
    while(_--) solve();
    return 0;
}

/*
题意:

    求最小割,但因为最小割是不唯一的,题目要求得到最小割的条件下,使得割边最少,输出最少割边数

思路:

    有两种做法,但本质是一样的

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

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

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

  第二种:

    建图,得到最大流后,图中边若满流,说明该边是最小割上的边

    再建图,原则:满流的边改为容量为 1 的边,未满流的边改为容量 INF 的边,然后最大流即答案
    */

hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割

时间: 2024-10-28 10:24:44

hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割的相关文章

HDU 3987 Harry Potter and the Forbidden Forest(最小割中的最少割边)经典

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1791    Accepted Submission(s): 596 Problem Description Harry Potter notices some Death Eaters try to slip

hdu 3987 Harry Potter and the Forbidden Forest【网路流最小割模型】

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1549    Accepted Submission(s): 528 Problem Description Harry Potter notices some Death Eaters try to slip

hdoj 3987 Harry Potter and the Forbidden Forest 【求所有最小割里面 最少的边数】

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1802    Accepted Submission(s): 602 Problem Description Harry Potter notices some Death Eaters try to slip

Harry Potter and the Forbidden Forest(割边最小的最小割)

Harry Potter and the Forbidden Forest Time Limit:3000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Description Harry Potter notices some Death Eaters try to slip into Castle. The Death Eaters hide in the most depths of Forbidden Forest.

HDU 4738——Caocao&#39;s Bridges——————【求割边/桥的最小权值】

Caocao's Bridges Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4738 Description Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. But he wouldn't give up. Caocao's army st

HDU3987 Harry Potter and the Forbidden Forest(边数最少的最小割)

方法1:两遍最大流.一遍最大流后,把满流边容量+1,非满流边改为INF:再求最小割即为答案. 我大概想了下证明:能构成最小割的边在第一次跑最大流时都满流,然后按那样改变边容量再求一次最小割,就相当于再在那些 满流可能是属于最小割的边 中挑出最少的边形成ST割. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std

HDU 3987 &amp;&amp; DINIC

很容易发现是网络流的题目,但最少边怎么求呢?初时想不到,但画图后忽然发现可以这样: 求一次网络流最小割后,把满流的边置1,不满流的置INF.再求一次最大流即可. 为什么呢? 是否会存在一些边当前不满流,但有可能是最少边数最少割的边呢?否.因为按照DINIC的求法,每次都是增广容量最少的路,若当前不满流,则必定不是最小割的边,所以只需在满流的边,即可组成最小割的边寻找最少边就可以了. 1 #include <iostream> 2 #include <cstring> 3 #incl

HDU 6214 Smallest Minimum Cut 最小割,权值编码

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6214 题意:求边数最小的割. 解法: 建边的时候每条边权 w = w * (E + 1) + 1; 这样得到最大流 maxflow / (E + 1) ,最少割边数 maxflow % (E + 1) 道理很简单,如果原先两类割边都是最小割,那么求出的最大流相等 但边权变换后只有边数小的才是最小割了 乘(E+1)是为了保证边数叠加后依然是余数,不至于影响求最小割的结果 因为假设最小割=k,那么现在新

HDU 4859 海岸线 最小割

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 题解: 这题考察的是最小割. 我们可以这样想:海岸线的长短变化都是E引起的,我们通过把’E'变成'.'或'D'来使海岸线最大化. 我们要算海岸线就是算格子‘.'和格子'D'(在原有地图周围四面都要加’D‘)相邻的面数,要使它最大,就是要使'.'与’.':'D'与'D'相邻的面数最小,而面数最小可以用最小割来做. 现在我们先把格子上的点黑白染色,(i+j)%2==1的为A类,为0的为B类, 在