HDU 5889 Barricade (bfs + 最小割)

Barricade

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Description

The empire is under attack again. The general of empire is planning to defend his castle. The land can be seen as N towns and M roads, and each road has the same length and connects two towns. The town numbered 1 is where general‘s castle is located, and the town numbered N is where the enemies are staying. The general supposes that the enemies would choose a shortest path. He knows his army is not ready to fight and he needs more time. Consequently he decides to put some barricades on some roads to slow down his enemies. Now, he asks you to find a way to set these barricades to make sure the enemies would meet at least one of them. Moreover, the barricade on the i-th road requires wi units of wood. Because of lacking resources, you need to use as less wood as possible.

Input

The first line of input contains an integer t, then t test cases follow.
For each test case, in the first line there are two integers N(N≤1000) and M(M≤10000).
The i-the line of the next M lines describes the i-th edge with three integers u,v and w where 0≤w≤1000 denoting an edge between u and v of barricade cost w.

Output

For each test cases, output the minimum wood cost.

Sample Input

1

4 4

1 2 1

2 4 2

3 1 3

4 3 4

Sample Output

4

/*
 * HDU 5889 Barricade
 * 求堵住从1到n的最短路的最小花费
 *
 * bfs + 最小割
 * 首先用Dij或者bfs求出dis数组,接着从终点出发,倒着bfs找出所有最短路径重新建图
 * 然后就是一个裸的最小割了,就等于最大流
 */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <map>
#include <vector>
using namespace std;

struct NetFlow
{
    const static int MAXN = 5000+10;
    const static int MAXE = 500000;
    const static long long INF = 1e18;
    struct Edge
    {
        int from,to,next,cap,flow;
        Edge(){}
        Edge(int u,int v,int c,int f,int nxt):from(u),to(v),cap(c),flow(f),next(nxt) {}
    }edge[MAXE];
    int head[MAXN],tol,N;
    int cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN];
    void init(int _n)
    {
        N=_n,tol=0; memset(head,-1,sizeof(head));
    }
    void link(int u,int v,int cap)//s->t,cap
    {
        edge[tol]=Edge(u,v,cap,0,head[u]);head[u]=tol++;
        edge[tol]=Edge(v,u,0,0,head[v]);head[v]=tol++;
    }
    long long ISAP(int S,int T)
    {//S -> T
        long long maxflow=0,aug=INF;
        int flag=false,u,v;
        for (int i=0;i<N;++i) cur[i]=head[i],gap[i]=dis[i]=0;
        for (gap[S]=N,u=pre[S]=S;dis[S]<N;flag=false)
        {
            for (int &it=cur[u];it!=-1;it=edge[it].next)
            {
                if (edge[it].cap>edge[it].flow&&dis[u]==dis[v=edge[it].to]+1)
                {
                    aug=min(aug,(long long)(edge[it].cap-edge[it].flow));
                    pre[v]=u,u=v; flag=true;
                    if (u==T)
                    {
                        for(maxflow+=aug;u!=S;)
                        {
                            edge[cur[u=pre[u]]].flow+=aug;
                            edge[cur[u]^1].flow-=aug;
                        }
                        aug=INF;
                    }
                    break;
                }
            }
            if(flag) continue;
            int mx=N;
            for(int it=head[u];it!=-1;it=edge[it].next)
            {
                if(edge[it].cap>edge[it].flow&&dis[edge[it].to]<mx)
                {
                    mx=dis[edge[it].to]; cur[u]=it;
                }
            }
            if((--gap[dis[u]])==0) break;
            ++gap[dis[u]=mx+1]; u=pre[u];
        }
        return maxflow;
    }
}NF;
const int MAXN = 5000+10;
const int MAXE = 200000;
const int INF = 1e9;
struct node{
    int v,c;
    node(int _v=0,int _c=0):v(_v),c(_c){}
    bool operator <(const node &rhs) const{
        return c>rhs.c;
    }
};
struct Ed
{
    int u,v,w;
}e;
vector<Ed>p;
struct Edge{
    int to,cost;
    int w;
    int next;
};
Edge edge[MAXE];
int head[MAXN],tot;
bool vis[MAXN];
int dis[MAXN];

void Dijkstra(int n,int start)
{
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++) dis[i]=INF;
    priority_queue<node>q;
    while(!q.empty()) q.pop();
    dis[start]=0;
    q.push(node(start,0));
    node next;
    while(!q.empty()){
        next=q.top();
        q.pop();
        int u=next.v;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            int cost=edge[i].cost;
            if(!vis[v]&&dis[v]>dis[u]+cost){
                dis[v]=dis[u]+cost;
                q.push(node(v,dis[v]));
            }
        }
    }
}

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

void addedge(int u,int v,int w,int ww)
{
    edge[tot].to=v;
    edge[tot].cost=w;
    edge[tot].w=ww;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void bfs(int T)
{
    memset(vis,0,sizeof(vis));
    queue<int>Q;
    Q.push(T);
    vis[T]=true;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int ds=edge[i].cost;
            int v=edge[i].to;
            if(ds+dis[v]==dis[u])
            {
                e.u=v,e.v=u,e.w=edge[i].w;
                p.push_back(e);
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v);
                }
            }
        }
    }
}

int main()
{
    int T;
    int n,m,u,v,w;
    //freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        init();
        p.clear();
        scanf("%d%d",&n,&m);
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,1,w);
            addedge(v,u,1,w);
        }
        Dijkstra(n,1);
        bfs(n);
        int sz=p.size();
        NF.init(n+1);
        for(int i=0;i<sz;i++)
        {
            u=p[i].u;
            v=p[i].v;
            w=p[i].w;
            NF.link(u,v,w);
        }
        long long ans=NF.ISAP(1,n);
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-11-05 12:19:09

HDU 5889 Barricade (bfs + 最小割)的相关文章

HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)

Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 997    Accepted Submission(s): 306 Problem Description The empire is under attack again. The general of empire is planning to defend his

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

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

hdu 4289 Control(最小割 + 拆点)

http://acm.hdu.edu.cn/showproblem.php?pid=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 Secu

HDU 4859 海岸线(最小割+最大独立点权变形)

http://acm.hdu.edu.cn/showproblem.php?pid=4859 题意: 欢迎来到珠海!由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的决策人,在仔细观察了Z市地图之后,你准备通过填充某些海域来扩展Z市的海岸线到最长,来吸引更多的游客前来旅游度假.为了简化问题,假设地图为一个N*M的格子,其中一些是陆地,一些是可以填充的浅海域,一些是不可填充的深海域.这里定义海岸线的长度为一个联通块陆地(可能包含浅海域填充变为的陆地)的边缘长度,两

HDU 5889 Barricade

最短路,最小割,网络流. 可以根据$dis[u]+1$与$dis[v]$的大小关系判断$<u,v>$是否为最短路上的边,可以处理出一个只包含最短路的$DAG$,然后求这个$DAG$的最小割就可以了. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<al

HDU 5294--Tricks Device【最小割 &amp;&amp; 最短路处理,新建图】

Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2208    Accepted Submission(s): 584 Problem Description Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu's at the en

hdu 3870(平面图最小割转最短路)

Catch the Theves Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65768/32768 K (Java/Others)Total Submission(s): 1640    Accepted Submission(s): 514 Problem Description A group of thieves is approaching a museum in the country of zjsxzy,now t

HDU 3452 Bonsai(最小割)

Bonsai Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 802    Accepted Submission(s): 406 Problem Description After being assaulted in the parking lot by Mr. Miyagi following the "All Valley Ka

HDU 3061 Battle(最小割 之 最大权闭包)经典

Battle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 983    Accepted Submission(s): 477 Problem Description 由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅.而他上任的第一天,就面对了一场极其困难的战斗: 据侦查兵回报,前方共有N座城池,考虑到地势原因,最终得到一个结