hdu 4289 网络流拆点,类似最小割(可做模板)邻接矩阵实现

Control

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2247    Accepted Submission(s): 940

Problem Description

 
 You, the head of Department of Security, recently received a top-secret
information that a group of terrorists is planning to transport some
WMD 1 from one city (the source) to another one (the
destination). You know their date, source and destination, and they are
using the highway network.
  The highway network consists of
bidirectional highways, connecting two distinct city. A vehicle can only
enter/exit the highway network at cities only.
  You may locate some
SA (special agents) in some selected cities, so that when the
terrorists enter a city under observation (that is, SA is in this city),
they would be caught immediately.
  It is possible to locate SA in
all cities, but since controlling a city with SA may cost your
department a certain amount of money, which might vary from city to
city, and your budget might not be able to bear the full cost of
controlling all cities, you must identify a set of cities, that:
  * all traffic of the terrorists must pass at least one city of the set.
  * sum of cost of controlling all cities in the set is minimal.
  You may assume that it is always possible to get from source of the terrorists to their destination.
------------------------------------------------------------
1 Weapon of Mass Destruction

Input

  There are several test cases.
 
 The first line of a single test case contains two integer N and M ( 2
<= N <= 200; 1 <= M <= 20000), the number of cities and the
number of highways. Cities are numbered from 1 to N.
  The second line contains two integer S,D ( 1 <= S,D <= N), the number of the source and the number of the destination.
 
 The following N lines contains costs. Of these lines the ith one
contains exactly one integer, the cost of locating SA in the ith city to
put it under observation. You may assume that the cost is positive and
not exceeding 107.
  The followingM lines tells you about
highway network. Each of these lines contains two integers A and B,
indicating a bidirectional highway between A and B.
  Please process until EOF (End Of File).

Output

  For each test case you should output exactly one line, containing one integer, the sum of cost of your selected set.
  See samples for detailed information.

Sample Input

5 6
5 3
5
2
3
4
12
1 5
5 4
2 3
2 4
4 3
2 1

Sample Output

3

Source

2012 ACM/ICPC Asia Regional Chengdu Online

大致题意:
    给出一个又n个点,m条边组成的无向图。给出两个点s,t。对于图中的每个点,去掉这个点都需要一定的花费。求至少多少花费才能使得s和t之间不连通。

大致思路:
    最基础的拆点最大流,把每个点拆作两个点 i 和 i‘ 连接i->i‘费用为去掉这个点的花费,如果原图中有一条边a->b则连接a‘->b。对这个图求出最大流即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

const int VM=420;
const int EM=500010;
const int INF=0x3f3f3f3f;

struct Edge{
    int to,nxt;
    int cap;
}edge[EM];

int n,m,src,des,cnt,head[VM];
int dep[VM];

void addedge(int cu,int cv,int cw){
    edge[cnt].to=cv;    edge[cnt].cap=cw;   edge[cnt].nxt=head[cu];
    head[cu]=cnt++;
    edge[cnt].to=cu;    edge[cnt].cap=0;    edge[cnt].nxt=head[cv];
    head[cv]=cnt++;
}

int BFS(){
    queue<int> q;
    while(!q.empty())
        q.pop();
    memset(dep,-1,sizeof(dep));
    dep[src]=0;
    q.push(src);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            if(edge[i].cap>0 && dep[v]==-1){
                dep[v]=dep[u]+1;
                q.push(v);
            }
        }
    }
    return dep[des]!=-1;
}

int DFS(int u,int minx){
    if(u==des)
        return minx;
    int tmp;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(edge[i].cap>0 && dep[v]==dep[u]+1 && (tmp=DFS(v,min(minx,edge[i].cap)))){
            edge[i].cap-=tmp;
            edge[i^1].cap+=tmp;
            return tmp;
        }
    }
    dep[u]=-1;
    return 0;
}

int Dinic(){
    int ans=0,tmp;
    while(BFS()){
        while(1){
            tmp=DFS(src,INF);
            if(tmp==0)
                break;
            ans+=tmp;
        }
    }
    return ans;
}

int main(){
    int s,t;
    while(~scanf("%d%d",&n,&m)){
        cnt=0;
        memset(head,-1,sizeof(head));
        scanf("%d%d",&s,&t);
        src=0, des=2*n+1;
        addedge(src,s,INF);
        addedge(n+t,des,INF);
        int u,v,w;
        for(int i=1;i<=n;i++){
            scanf("%d",&w);
            addedge(i,n+i,w);
            addedge(n+i,i,w);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            addedge(n+u,v,INF);     //注意这里的建边,src--->s--->u(某条边)---->n+u(拆分u点后的另一点)---->v---->n+v(拆分v点后的另一点)---->u-----
            addedge(n+v,u,INF);     //所以,addedge(n+u,v,INF);仔细想想,这样才能保证 u 和 v 使连接着的
        }
        printf("%d\n",Dinic());
    }
    return 0;
}
时间: 2024-10-23 02:15:56

hdu 4289 网络流拆点,类似最小割(可做模板)邻接矩阵实现的相关文章

HDU 3251 Being a Hero(最小割)经典

Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1229    Accepted Submission(s): 387 Special Judge Problem Description You are the hero who saved your country. As promised, the ki

hdoj 4289 Control 【拆点 求最小割】

Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2295    Accepted Submission(s): 961 Problem Description You, the head of Department of Security, recently received a top-secret informati

HDU 3035 War(对偶图求最小割)

HDU 3035 War 题目链接 题意:根据图那样,给定一个网络,要求阻断s到t,需要炸边的最小代价 思路:显然的最小割,但是也显然的直接建图强行网络流会超时,这题要利用平面图求最小割的方法,把每一块当成一个点,共有边连边,然后每一个路径就是一个割,然后最短路就是最小割了 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace s

【网络流】线性规划的最小割建模方式

前几天在师大附中听课,大概了解了一些关于网络流的建模方式,然后今天上午做了一些题目,在这里总结一下. 最小割的线性规划建模方式: 有一些0/1变量Xi,怎么怎么样之后会消耗某些代价或者获得某些利益,而最后的总收益可以写成如下的形式: min{ Σmax{Xi-Xj,0}*Wi } 其中Wi必须是正数. 那么假设源为1,汇为0,就将Xi连一条流量为Wi的边到Xj. 如果有形如1-Xi之类的形式就是从源向Xi连边,Xi-0这种形式就是Xi向汇点连边. 那么如果Wi是负数怎么办? 比如Xi*Wi(Wi

HDU 5889 Barricade(最短路+最小割)

http://acm.hdu.edu.cn/showproblem.php?pid=5889 题意: 给出一个图,帝国将军位于1处,敌军位于n处,敌军会选择最短路到达1点.现在帝国将军要在路径上放置障碍,每条边上都有一个放置障碍的代价.求至少需要多少代价. 思路: 首先就是求最短路,然后将最短路上的边重新进行构图跑最小割即可. 一开始求了两遍bfs,分别求出起点到各个点的距离和终点到各个点的距离,然后去判断每条边是否在最短路中,但是这样的话在最大流的构图中无法确定方向,然后就一直Wa... 其实

Hdu 3691 Nubulsa Expo(无向图最小割)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3691 思路:无向图最小割模板题. 流量最小且汇点自定,则可在最小割T集中任选一点当做汇点. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define debu using namespace std; const int maxn=350; const in

HDU - 3002 King of Destruction(最小割)

http://acm.hdu.edu.cn/showproblem.php?pid=3002   最小割模板 #include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<cstdio> #include<algorithm> #include<map> #include<set

HDU - 3035 War(对偶图求最小割+最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3035 题意 给个图,求把s和t分开的最小割. 分析 实际顶点和边非常多,不能用最大流来求解.这道题要用平面图求最小割的方法: 把面变成顶点,对每两个面相邻的边作一条新边.然后求最短路就是最小割了. 另外,外平面分成两个点,分别是源点和汇点,源点连左下的边,汇点连右上的边,这样跑出来才是正确的. 建图参考自:https://blog.csdn.net/accelerator_/article/deta

HDU 3215 Being a Hero(最小割)

题意:一个英雄,分到几个城市,每个城市有一个价值,但是要求分到城市后,必须破坏掉道路使得首都1都不能到达,破坏道路有开销,问最大能获得的收益和需要破坏的道路ID 思路:最小割,城市1做源点,有向边建图,容量为代价,然后每个可以分的城市连到汇点,容量为价值,跑一下最小割即可 代码: [cpp] view plaincopy #include <cstdio> #include <cstring> #include <queue> #include <algorith