hdu 5889 Barricade【最短路SPFA+最小割--------Dinic】

时间:2022-12-24 04:26:08

Barricade

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 759    Accepted Submission(s): 224

Problem 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

Source

2016 ACM/ICPC Asia Regional Qingdao Online

Recommend

wange2014   |   We have carefully selected several similar problems for you:  5901 5900 5899 5898 5897 

 

 题目大意:

 有n个点,m条无向边。敌人在点n想要攻击到点1,每次敌人一定走的都是最短路,如果我们不想要敌人从n出发走到点1,去掉每一条边都有对应的权值,求这个最小权值花费。


思路:


1、因为敌人每一次走的都是最短路,那么我们首先以点n做一遍单源最短路,求出dis【】;


2、那么我们将网络建立:

①设定n为源点,设定1为汇点。

②将dis【v】==dis【u】+1的边加入到网络中,流设定为其对应的权值。


3、那么我们跑一遍最大流,根据最大流最小割定理,我们得到的最大流就是最小割,那么就是这个最小花费。


Ac代码:

#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
struct node
{
    int from;
    int to;
    int w;
    int next;
}e[1500000];
int x[100000];
int y[100000];
int ww[100000];
int dis[100000];
int vis[100000];
int head[100000];
int cur[100000];
int divv[100000];
vector<int >mp[100000];
int n,m,cont,ss,tt;
void add(int from,int to,int w)
{
    e[cont].to=to;
    e[cont].w=w;
    e[cont].next=head[from];
    head[from]=cont++;
}
void getmap()
{
    ss=n;
    tt=1;
    cont=0;
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;i++)
    {
        int u=x[i];
        int v=y[i];
        int w=ww[i];
        if(dis[u]==dis[v]+1)
        {
            add(v,u,w);
            add(u,v,0);
        }
        if(dis[v]==dis[u]+1)
        {
            add(u,v,w);
            add(v,u,0);
        }
    }
}
void SPFA()
{
    ss=n;
    tt=1;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)dis[i]=0x3f3f3f3f;
    dis[ss]=0;
    queue<int >s;
    s.push(ss);
    while(!s.empty())
    {
        int u=s.front();
        vis[u]=0;
        s.pop();
        for(int i=0;i<mp[u].size();i++)
        {
            int v=mp[u][i];
            int w=1;
            if(dis[v]>dis[u]+w)
            {
                dis[v]=dis[u]+w;
                if(vis[v]==0)
                {
                    vis[v]=1;
                    s.push(v);
                }
            }
        }
    }
}
int makedivv()
{
    memset(divv,0,sizeof(divv));
    divv[ss]=1;
    queue<int >s;
    s.push(ss);
    while(!s.empty())
    {
        int u=s.front();
        if(u==tt)return 1;
        s.pop();
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int w=e[i].w;
            int v=e[i].to;
            if(divv[v]==0&&w)
            {
                divv[v]=divv[u]+1;
                s.push(v);
            }
        }
    }
    return 0;
}
int Dfs(int u,int maxflow,int tt)
{
    if(u==tt)return maxflow;
    int ret=0;
    for(int &i=cur[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        int w=e[i].w;
        if(divv[v]==divv[u]+1&&w)
        {
            int f=Dfs(v,min(maxflow-ret,w),tt);
            e[i].w-=f;
            e[i^1].w+=f;
            ret+=f;
            if(ret==maxflow)return ret;
        }
    }
    return ret;
}
void Dinic()
{
    int ans=0;
    while(makedivv()==1)
    {
        memcpy(cur,head,sizeof(head));
        ans+=Dfs(ss,0x3f3f3f3f,tt);
    }
    printf("%d\n",ans);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)mp[i].clear();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x[i],&y[i],&ww[i]);
            mp[x[i]].push_back(y[i]);
            mp[y[i]].push_back(x[i]);
        }
        SPFA();
        getmap();
        Dinic();
    }
}