首页 > 其他分享 >UVA1658 Admiral 题解

UVA1658 Admiral 题解

时间:2023-12-11 16:34:31浏览次数:29  
标签:UVA1658 int 题解 flow vis cost maxn Admiral dis

Link

UVA1658 Admiral

Question

给出一个图,找出 \(1 \sim n\) 的两条,使得路径和最小

Solution

可以把点拆开,把除了 \(1\) 和 \(n\) 的点 \(i\) ,拆成 \(i\) 和 \(i'\) ,\(i\) 到 \(i'\) 连一条费用为 \(0\) ,容量为 \(1\) 的边,如果原来有一条边 \(u-v\) ,那么就建立一条 \(u'->v\) ,费用为 \(w_{u,v}\),容量为 \(1\) 的边

之后刷 \(1\sim n\) ,流量为 \(2\) 的最大费用就是答案

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=1<<30;
const int maxn=2010;

struct Edge{
    int from,to,cap,flow,cost;
    Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),flow(f),cost(w){}
};

struct Dinic{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    int vis[maxn];
    int dis[maxn];
    int a[maxn];  //起点到 i 的可改进量
    int cur[maxn]; //当前弧
    

    void init(int n){
        this->n=n;
        for(int i=0;i<n;i++) G[i].clear();
        edges.clear();
    }

    void add_e(int from,int to,int cap,int cost){
        // printf("%d %d %d %d\n",from,to,cap,cost);
        edges.push_back(Edge(from,to,cap,0,cost));
        edges.push_back(Edge(to,from,0,0,-cost));
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool SPFA(){
        for(int i=1;i<=n;i++)dis[i]=INF;
        memset(vis,0,sizeof vis);
        queue<int> Q;
        Q.push(s);dis[s]=0;vis[s]=1;a[s]=INF;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            vis[u]=0;
            for(int i=0;i<G[u].size();i++){
                Edge& e=edges[G[u][i]];
                if(e.cap-e.flow>0&&dis[e.to]>dis[u]+e.cost){
                    dis[e.to]=dis[u]+e.cost;
                    a[e.to]=min(a[u],e.cap-e.flow);
                    if(!vis[e.to]){Q.push(e.to);vis[e.to]=1;}
                }
            }
        }
        if(dis[t]==INF) return false;
        return true;
    }
    
    int DFS(int u,int a){
        if(a==0||u==t) return a;
        vis[u]=1;
        int flow=0,cost=0,f;
        for(int& i=cur[u];i<G[u].size();i++){
            Edge &e=edges[G[u][i]];
            if(!vis[e.to] && dis[u]+e.cost==dis[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edges[G[u][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    }

    int MincostMaxflow(int s,int t,LL& cost){
        this->s=s,this->t=t;
        int flow=0;
        while(SPFA()){
            memset(vis,0,sizeof vis);
            memset(cur,0,sizeof cur);
            int now_flow=DFS(s,INF);
            flow+=now_flow;
            cost+=dis[t]*now_flow;
        }
        return flow;
    }
};


int main(){
    int n,m;
    while(cin>>n>>m){
        Dinic F;
        F.init(2*n+2);
        int st=2*n+1,ed=2*n+2;
        
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d %d %d",&x,&y,&z);
            if(x!=1&&x!=n)
                F.add_e(x+n,y,1,z);
            else 
                F.add_e(x,y,1,z);
        }
        for(int i=2;i<n;i++){
            F.add_e(i,i+n,1,0);
        }
        F.add_e(st,1,2,0);F.add_e(n,ed,2,0);
        LL cost=0;
        F.MincostMaxflow(st,ed,cost);
        printf("%lld\n",cost);
    }
    return 0;
}

标签:UVA1658,int,题解,flow,vis,cost,maxn,Admiral,dis
From: https://www.cnblogs.com/martian148/p/17894730.html

相关文章

  • P2341 受欢迎的牛 G 题解
    LinkP2341[USACO03FALL/HAOI2006]受欢迎的牛GQuestion牛栏中有\(N\)头奶牛,和一些\(M\)对爱慕关系,A->B表示A爱慕B。每个奶牛都喜欢自己,被所有奶牛喜欢就是一头明星奶牛,求明星奶牛的数量Solution考虑一个强连通分量里面的奶牛是相互爱慕的,先根据强连通分量缩点,缩......
  • 题解 QOJ1173【Knowledge Is...】 / accoders::NOI 5681【interval】
    https://qoj.ac/contest/537/problem/1173problem给定\(n\leq10^6\)个区间,你需要求出能够最多选出多少对区间,使得两个区间不交(区间为闭区间)。要求一个区间最多属于一对选出的区间。solution这是一般图匹配问题的特殊情况,所以放弃dp,考虑贪心、网络流、匹配等。按照左端点......
  • P5048 [Ynoi2019 模拟赛] 题解
    题意给定\(n\)个数,有\(m\)个询问,每个询问给定\(l\)和\(r\),求出区间\(l\)到\(r\)中的最小众数出现次数,强制在线。数据范围:\(n\le500000\),空间限制:\(62.5MB\)。思路这道题的弱化版是蒲公英,这道题加强的地方在于数据范围。正常的分块求区间众数的空间复杂度是\(O(n......
  • CF1842E Tenzing and Triangle 题解
    题意不多赘述。思路如果两个所选的三角形有重合部分的话,那么这种情况肯定是不会出现的。因为如果把这两个三角形合成一个大三角形的话,不仅覆盖面积会增大,而且花费的代价还不会多。于是我们可以想到用dp来解决,设\(dp_{i}\)表示删完横坐标为\(0\)到\(i\)中的点的最小代价......
  • [ABC304Ex] Constrained Topological Sort 题解
    题意给定一张有向图\(G\),有\(n\)个点和\(m\)条边,问是否存在一种拓扑序的排列\(P\)使得\(l_{i}\lep_{i}\ler_{i}\)。思路首先对于一条边\(u\tov\),如果限制满足\(r_{v}\ler_{u}\)或者\(l_{v}\gel_{u}\)的话,那么这个限制其实是不完全正确的。因为最终的序列......
  • 【题解】AtCoder abc322_f Random Update Query
    传送门:https://atcoder.jp/contests/abc332/tasks/abc332_f容易发现,对于一个位置$i$,$A_i$的最终值是由对$i$的最后一次赋值操作决定的;因此,将所有操作按时间顺序倒过来考虑,则由第$j$次操作决定$A_i$最终值的概率为"在第$(j+1)$~$m$次操作中没有修改过$i$的概率"与"第......
  • 【题解】AtCoder abc332_g Not Too Many Balls
    传送门:https://atcoder.jp/contests/abc332/tasks/abc332_g看完题,第一眼反应为最大流。建模方式为:以颜色为左部点,盒子为右部点,源点$S$向颜色$i$连一条容量为$A_i$的边,盒子$j$向汇点$T$连一条容量为$B_j$的边,颜色$i$向盒子$j$连一条容量为$ij$的边;在这张图......
  • AT_cf17_final_j Tree MST 题解
    题意:给定一颗\(n\)个点的树,点\(i\)有权值\(a_{i}\),边有边权。现在有另外一个完全图,两点之间的边权为树上两点之间的距离加上树上两点的点权,求这张完全图的最小生成树。首先有一个很显然的暴力,把完全图中每两点之间的边权算出来,然后跑一边最小生成树,时间复杂度\(O(n^{2}\lo......
  • P7735 [NOI2021] 轻重边 题解
    是一道树剖好题,之前听lsl讲过一点,于是很快就做出来了。题意:有一个\(n\)个节点的树,最开始的时候所有边都是轻边,维护两个操作:操作一:将\(u\)到\(v\)的路径中经过的所有点的邻边变为轻边,再将这条路径上的边变为重边。操作二:求出\(u\)到\(v\)这条路径上有多少条重边......
  • 小程序建立用户与数据的联系问题解决方案
    在小程序中建立用户与数据的联系是一个常见的问题,在本文中提供了一个解决方案。这个解决方案包括几个关键步骤。首先,需要通过用户登录功能实现用户的身份识别,并获取到用户的唯一标识符。接着,需要在后台数据库中创建一个用户表,用于存储用户的基本信息和与之相关联的数据。在这个表中......