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<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-‘0‘; c=getchar();}
}

const int maxn = 30000 + 10;
const int INF = 0x7FFFFFFF;
struct Edge
{
    int from, to, cap, flow;
    Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}
};
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int n, m, s, t;

void init()
{
    for (int i = 0; i < maxn; i++)
        G[i].clear();
    edges.clear();
}
void AddEdge(int from, int to, int cap)
{
    edges.push_back(Edge(from, to, cap, 0));
    edges.push_back(Edge(to, from, 0, 0));
    int w = edges.size();
    G[from].push_back(w - 2);
    G[to].push_back(w - 1);
}
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 = 0; i<G[x].size(); i++)
        {
            Edge e = edges[G[x][i]];
            if (!vis[e.to] && e.cap>e.flow)
            {
                vis[e.to] = 1;
                d[e.to] = d[x] + 1;
                Q.push(e.to);
            }
        }
    }
    return vis[t];
}
int DFS(int x, int a)
{
    if (x == t || a == 0)
        return a;
    int flow = 0, f;
    for (int &i = cur[x]; i<G[x].size(); i++)
    {
        Edge e = edges[G[x][i]];
        if (d[x]+1 == d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
        {
            edges[G[x][i]].flow+=f;
            edges[G[x][i] ^ 1].flow-=f;
            flow+=f;
            a-=f;
            if(a==0) break;
        }
    }
    if(!flow) d[x] = -1;
    return flow;
}
int dinic(int s, int t)
{
    int flow = 0;
    while (BFS())
    {
        memset(cur, 0, sizeof(cur));
        flow += DFS(s, INF);
    }
    return flow;
}

int h[maxn],sz,T;
struct X
{
    int u,v,w,nx;
}ee[maxn];
int dis[maxn],flag[maxn];

void add(int a,int b,int c)
{
    ee[sz].u=a; ee[sz].v=b; ee[sz].w=c;
    ee[sz].nx=h[a]; h[a]=sz++;
}

void spfa()
{
    for(int i=1;i<=n;i++) dis[i]=INF ,flag[i]=0;
    dis[1]=0; queue<int>Q; Q.push(1); flag[1]=1;

    while(!Q.empty())
    {
        int top=Q.front(); Q.pop(); flag[top]=0;
        for(int i=h[top];i!=-1;i=ee[i].nx)
        {
            if(dis[top]+1<dis[ee[i].v])
            {
                dis[ee[i].v]=dis[top]+1;
                if(flag[ee[i].v]==0)
                {
                    flag[ee[i].v]=1;
                    Q.push(ee[i].v);
                }
            }
        }
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m); sz=0;
        memset(h,-1,sizeof h);
        for(int i=1;i<=m;i++)
        {
            int u,v,w; scanf("%d%d%d",&u,&v,&w);
            add(u,v,w); add(v,u,w);
        }
        spfa();

        init();
        for(int i=0;i<sz;i++)
        {
            if(dis[ee[i].u]+1==dis[ee[i].v])
            {
                AddEdge(ee[i].u,ee[i].v,ee[i].w);
            }
        }
        s=1; t=n;
        printf("%d\n",dinic(s,t));
    }
    return 0;
}
时间: 2024-10-25 15:01:35

HDU 5889 Barricade的相关文章

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

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 5889 (最短路+网络流)

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

HDU 5889【最小割+最短路】

题意:给出一张n个点m条边的无向图,边权均为1,敌人在n点准备走最短路在攻击己方位置1点,现在要在一些边上设置一些路障,给出每条边设置路障的代价,要求用最少的代价设置路障使得敌人必然遇到路障. 这份代码了用到了当前弧优化,尽管我不是很懂... 但素不用的话会超时! #include<stdio.h> #include<string.h> #include<queue> using namespace std; struct node { int from; int to

【2016 ACM/ICPC Asia Regional Qingdao Online】

[ HDU 5878 ] I Count Two Three 考虑极端,1e9就是2的30次方,3的17次方,5的12次方,7的10次方. 而且,不超过1e9的乘积不过5000多个,于是预处理出来,然后每次二分找就可以了. /* TASK:I Count Two Three 2^a*3^b*5^c*7^d的最小的大于等于n的数是多少 LANG:C++ URL:http://acm.hdu.edu.cn/showproblem.php?pid=5878 */ #include <iostream>

[HDOJ5889]Barricade(spfa,最大流)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5889 求出所有最短路,标记好以后跑最大流就是最小割. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define fr first 4 #define sc second 5 #define cl clear 6 #define BUG puts("here!!!") 7 #define W(a) while(a--)

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include