zoukankan      html  css  js  c++  java
  • HDU6582 Path 最短路+最小割

    网址:https://vjudge.net/problem/HDU-6582

    题意:

    给出一个有向无环有重边图,删除一条边的代价就是边的长度,求使得点$1$和点$n$的最短路变长或者不存在最短路的最小代价。

    题解:

    对于一个图两点的最短路中构成的边构成的子图,如果在这个子图中两点不连通,则在实际的图中,最短路一定变长或甚至不存在最短路。故求一次点$1$到其他点的最短路,记录所有最短路上的边,建立子图,求子图上的最小割,即最大流。对于所有边,如果边的两个端点的最短路长度差的绝对值等于边权,则说明这条边在最短路上。

    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+5;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    const int inf=0x3f3f3f3f;
    #define ll long long
    struct Edge
    {
        int u,v;
        long long w;
        Edge(int a,int b,long long c)
        {
            u=a,v=b,w=c;
        }
        bool operator<(const Edge &a)const
        {
            return w>a.w;
        }
    };
    vector<Edge>Eo[MAXN];
    long long diss[MAXN];
    bool vis[MAXN];
    void dijkstra()
    {
        memset(diss,inf,sizeof(diss));
        memset(vis,0,sizeof(vis));
        priority_queue<Edge>que;
        diss[1]=0;
        que.push(Edge(1,1,0));
        while(!que.empty())
        {
            auto tmp=que.top();
            que.pop();
            if(vis[tmp.v])
                continue;
            vis[tmp.v]=1;
            for(auto &e:Eo[tmp.v])
            {
                if(diss[e.v]>diss[tmp.v]+e.w)
                {
                    diss[e.v]=diss[tmp.v]+e.w;
                    if(!vis[e.v])
                        que.push(Edge(tmp.v,e.v,diss[e.v]));
                }
            }
        }
    }
    
    //最大流模板
    int sp,tp;//原点、汇点 
    struct node
    {
    	int v,next;
    	ll cap;
    }mp[MAXN*4];
    int pre[MAXN],dis[MAXN],cur[MAXN];//cur为当前弧优化,dis存储分层图中每个点的层数(即到原点的最短距离),pre建邻接表
    int cnt=0;
    void init()//不要忘记初始化
    {
    	cnt=0;
    	memset(pre,-1,sizeof(pre));
    }
    void add(int u,int v,int w)//加边 
    {
    	mp[cnt].v=v;
    	mp[cnt].cap=w;
    	mp[cnt].next=pre[u];
    	pre[u]=cnt++;
    }
    bool bfs()//建分层图
    {
    	memset(dis,-1,sizeof(dis));
    	queue<int>q;
    	while(!q.empty())
    	q.pop();
    	q.push(sp);
    	dis[sp]=0;
    	int u,v;
    	while(!q.empty())
    	{
    		u=q.front();
    		q.pop();
    		for(int i=pre[u];i!=-1;i=mp[i].next)
    		{
    			v=mp[i].v;
    			if(dis[v]==-1&&mp[i].cap>0)
    			{
    				dis[v]=dis[u]+1;
    				q.push(v);
    				if(v==tp)
    				break;
    			}
    		}
    	}
    	return dis[tp]!=-1;
    }
    ll dfs(int u,ll cap)//寻找增广路
    {
    	if(u==tp||cap==0)
    	return cap;
    	ll res=0,f;
    	for(int &i=cur[u];i!=-1;i=mp[i].next)
    	{
    		int v=mp[i].v;
    		if(dis[v]==dis[u]+1&&(f=dfs(v,min(cap-res,mp[i].cap)))>0)
    		{
    			mp[i].cap-=f;
    			mp[i^1].cap+=f;
    			res+=f;
    			if(res==cap)
    			return cap;
    		}
    	}
    	if(!res)
    	dis[u]=-1;
    	return res;
    }
    ll dinic(int n)
    {
    	ll ans=0;
    	while(bfs())
    	{
    		for(int i=1;i<=n;i++)
    		    cur[i]=pre[i];
    		ans+=dfs(sp,inf);
    	}
    	return ans;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        int T;
        cin>>T;
        while(T--)
        {
            int n,m,a,b,c;
            cin>>n>>m;
            for(int i=1;i<=n;++i)
                Eo[i].clear();
            for(int i=0;i<m;++i)
            {
                cin>>a>>b>>c;
                Eo[a].push_back(Edge(a,b,c));
            }
            dijkstra();
            sp=1,tp=n;
            init();
            //cout<<endl;
            for(int i=1;i<=n;++i)
                for(auto &e:Eo[i])
                    if(diss[e.v]-diss[e.u]==e.w)
                    {
                        add(e.u,e.v,e.w);
                        add(e.v,e.u,0);
                    }
            cout<<dinic(n)<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    rabbitmq学习之路(五)
    rabbitmq学习之路(四)
    rabbitmq学习之路(三)
    rabbitmq学习之路(二)
    rabbitmq学习之路(一)
    回忆一下数据库中的锁问题
    feign+hystrix 进行服务降级
    vue.js之过滤器,自定义指令,自定义键盘信息以及监听数据变化
    node.js之用ajax获取数据和ejs获取数据
    用node.js实现mvc相册资源管理器
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/11260555.html
Copyright © 2011-2022 走看看