HDU5294 Tricks Device(最大流+最短路)

news/2024/7/7 17:22:30

题目链接

  一个无向图,走最短路从起点走到终点,问最少需要删除多少边使得其不能从起点走到终点,问最多删除多少点使得其能走到终点。

思路:

  最大流+最短路

  先求出所有在最短路上的边,对这些边重建图。将其权值改为1,那么其最大流就是其最小割。

#include<bits/stdc++.h>
using namespace std;

const int maxn=2110;
const int maxm=12e4+10;
const int inf=0x3f3f3f3f;

int head[maxn],vis[maxn],dis[maxn],x[maxm],y[maxm],z[maxm],sum[maxn],len,nedge,n,m,st,en;

struct Edge
{
    int v,w;
    int next;
}edge[maxm<<1];

void addedge(int u,int v,int w)
{
    edge[nedge].v=v;
    edge[nedge].w=w;
    edge[nedge].next=head[u];
    head[u]=nedge++;
}

int spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        sum[i]=dis[i]=(i==st)?0:inf;
    queue<int>q;
    q.push(st);
    vis[st]=1;
    while(q.size())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v ;
            if(edge[i].w&&dis[u]+edge[i].w<dis[v])
            {
                dis[v]=dis[u]+edge[i].w;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return dis[en];
}

bool bfs()
{
    queue<int>q;
    memset(dis,-1,sizeof(dis));
    dis[st]=0;
    q.push(st);
    while(q.size())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v ;
            if(edge[i].w>0&&dis[v]<0)
            {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
    }
    if(dis[en]>0)
        return true ;
    return false ;
}

int dfs(int x,int mx)
{
    if(x==en)
        return mx;
    int i,ans=0,a;
    for(i=head[x];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w))))
        {
            edge[i].w-=a;
            edge[i^1].w+=a;
            ans+=a;
            mx-=a;
            if(!mx)
                break;
        }
    }
    if(!ans)
        dis[x] = -1;
    return ans;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(head,-1,sizeof(head));
        nedge=0;
        len=0;
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
            x[len]=u,y[len]=v,z[len++]=w;
            x[len]=v,y[len]=u,z[len++]=w;
        }
        st=1,en=n;
        int mi=spfa();
        if(mi==inf)
        {
            printf("0 0\n");
            continue;
        }
        memset(head,-1,sizeof(head));
        nedge=0;
        for(int i=0;i<len;i++)
        if(dis[x[i]]+z[i]==dis[y[i]])
        {
            addedge(x[i],y[i],1);
            addedge(y[i],x[i],0);
        }
        mi=spfa();
        int ans=0,res;
        while(bfs())
          while(res=dfs(st,inf))
            ans+=res;
        printf("%d %d\n",ans,m-mi);
    }
    return 0;
}

 


http://www.niftyadmin.cn/n/3620848.html

相关文章

P3119 [USACO15JAN]Grass Cownoisseur G(tarjan+dp)

LINK 先缩点,在DAGDAGDAG上跑最长路可以得到dis[v]dis[v]dis[v] 表示111号点的联通分量到vvv连通分量最多走多少草坪 当走到uuu点时使用反向机会走到点vvv,其中vvv一定是能到达点111所属的连通分量的 所以以111所在联通分量为起点,终点分别跑一次最长路 然后枚举那个中转点…

训练总结 18.7.18 暑假训练第三天

今日完成题量两道。 两道题&#xff0c;一道线段树&#xff0c;一道网络流。线段树那道题有点迷&#xff0c;RE了好几次&#xff0c;线段树一直都应用不大熟练。网络流今天刚补的知识点&#xff0c;勉强看懂&#xff0c;应用相当不熟练&#xff0c;今天的题目最大流最短路&…

CodeSmith 二、多模板按目录树批量自动生成代码

通过调用指定目录下的所有模板&#xff0c;逐一按照数据表生成独立的代码文件。支持多模板调用、支持所有数据表生成或批量指定多个生成、支持自动的文件目录结构、支持代码文件格式化命名等。 背景&#xff1a;最近一个新项目一高兴选了Mysql 8&#xff0…

康威定律-软件之道:软件开发争议问题剖析

每个架构师都应该研究下康威定律 http://36kr.com/p/5042735.html 软件之道:软件开发争议问题剖析((美)AndyOram) http://baike.baidu.com/view/11495670.htm

斯坦福机器学习视频笔记 Week4 Week5 神经网络 Neural Networks

神经网络是一种受大脑工作原理启发的模式。 它在许多应用中广泛使用&#xff1a;当您的手机解释并理解您的语音命令时&#xff0c;很可能是神经网络正在帮助理解您的语音; 当您兑现支票时&#xff0c;自动读取数字的机器也使用神经网络。 Non-linear Classification 当输入数据…

如何利用几何画板解方程

解方程的方法不止一种&#xff0c;可以用正常方法解&#xff0c;也可以用公式法或一些较好的计算器&#xff0c;但是这两种方法都比较繁琐&#xff0c;下面介绍如何利用几何画板解方程的方法。 具体的操作步骤如下&#xff1a; 步骤一 新建一个网格。打开几何画板软件&#xff…

P5058 [ZJOI2004]嗅探器(割点的理解)

LINK 答案必定是某个割点,但是割点并不一定是答案 移除割点后,原图被分成若干个部分,如何判断a,ba,ba,b在不同的连通块?? 我们知道,我们认定uuu是割点是因为存在 dfn[u]<low[v]dfn[u]<low[v]dfn[u]<low[v] 此时vvv的子树无法回到更浅的节点,割掉uuu,将与其他部分…

训练总结 18.7.19 暑假训练第四天

今天上午新开的专题做了三道题&#xff0c;是之前做过的题。之前把思路理清了做起来还是比较顺利。 下午的比赛&#xff0c;虽然之前有心理准备&#xff0c;但做起来还是怪难受的。签个到都难&#xff0c;最后那道题目&#xff0c;一开始想着预处理一下&#xff0c;然后直接查询…