• 2020牛客暑期多校训练营(第二场)Interval 网络流平面图转化成最短路


    题目链接:Interval

    题目大意:

    给你一个区间 ([l,r]) 这个区间可能做两种操作:

    • 收缩, ([l,r]) 变成 ([l,r-1]) 或者 ([l+1,r])
    • 扩张,([l,r]) 变成 ([l-1,r]) 或者 ([l,r+1])

    但是当 (l==r) 的时候,这个区间就不会有任何的变化了,你不想看到这样的情况,所以你要禁止一些操作。

    ((l,r,dir,c)) 对于这个元组表示:

    • 如果 (dir=L) 那么你可以花费 (c) 禁止 ([l,r])([l + 1,r]) 的改变
    • 如果 (dir = R) 那么你可以花费 (c) 禁止 ([l,r])([l,r-1]) 的改变。

    算出最小的花费保证 (l\,!=r) ,如果不可能,则输出 (-1)

    题解:

    这个题目还是有点难的,知道这个是一个网络流了,但是我还是不知道怎么建图,先看看官方题解吧:

    看完之后就先去学了一些怎么把平面图转对偶图然后求最短路

    学习推荐博客:https://www.cnblogs.com/lher/p/7856451.html

    看完之后就应该先去自己写一下狼抓兔子这个题目了:https://www.luogu.com.cn/problem/P4001

    狼抓兔子题解:https://www.cnblogs.com/EchoZQN/p/13322359.html

    自己做完就应该知道怎么把平面图转化成对偶图了。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    #define debug(x) printf("debug:%s=%d
    ",#x,x);
    //#define debug(x) cout << #x << ": " << x << endl;
    using namespace std;
    typedef long long ll;
    const int maxn = 500+5;
    int t,s;
    struct node{
        ll w;
        int u,v;
        node(int u=0,int v=0,ll w=0):u(u),v(v),w(w){}
    };
    struct heapnode{
        ll d;
        int u;
        heapnode(ll d,int u) : d(d),u(u) {}
        bool operator<(const heapnode &a) const{
            return a.d<d;
        }
    };
    vector<node>e[2*maxn*maxn];
    void add(int u,int v,ll w){
    //    printf("u=%d v=%d w=%lld
    ",u,v,w);
        e[u].push_back(node(u,v,w));
        e[v].push_back(node(v,u,w));
    }
    ll d[2*maxn*maxn];
    bool vis[2*maxn*maxn];
    priority_queue<heapnode>que;
    void dij(int s){
        while(!que.empty()) que.pop();
        for(int i=0;i<=t+10;i++) d[i]=inf64;
        d[s]=0;
        que.push(heapnode(0,s));
        while(!que.empty()){
            heapnode x=que.top();que.pop();
            int u=x.u;
            if(vis[u]) continue;
            vis[u]=1;
            for(int i=0;i<e[u].size();i++){
                node now=e[u][i];
                if(d[now.v]>d[u]+now.w){
                    d[now.v]=d[u]+now.w;
                    que.push(heapnode(d[now.v],now.v));
                }
            }
        }
    }
    
    ll w[maxn][maxn][2];
    char ss[10];
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        memset(w,inf64,sizeof(w));
        s = 0, t = (n-1)*(n-1)+1;
        for (int i = 1; i <= m; i ++) {
            int u,v,c;
            scanf("%d%d%s%d",&u,&v,ss,&c);
            if(ss[0]=='L') w[u][v][1]=c;
            else w[u][v][0]=c;
        }
        for(int i=1;i<n-1;i++){
            for(int j=i;j<n;j++){
                int u = (i-1)*(n-1)+j;
                int x = (i-1)*(n-1)+j+1;
                int y = i*(n-1)+j;
                if(i==j) y ++;
                if(x<=i*(n-1)) add(u,x,w[i][j+1][1]);
                add(u,y,w[i+1][j+1][0]);
    //            printf("i=%d j=%d
    ",i,j);
    //            printf("u=%d x=%d y=%d w1=%lld w2=%lld
    ",u,x,y,w[i][j+1][1],w[i+1][j+1][0]);
            }
        }
        for(int j=1;j<n;j++){
            int u = j;
            add(s,u,w[1][j+1][0]);
            int v = j*(n-1);
            add(t,v,w[j][n][1]);
        }
        dij(s);
        if(d[t]>=inf64) printf("-1
    ");
        else printf("%lld
    ",d[t]);
        return 0;
    }
    /*
    6 6
    5 6 L 6
    2 3 R 2
    5 6 R 3
    5 6 R 8
    1 6 L 1
    1 5 R 10
    
     */
    
  • 相关阅读:
    CodeForces 156B Suspects(枚举)
    CodeForces 156A Message(暴力)
    CodeForces 157B Trace
    CodeForces 157A Game Outcome
    HDU 3578 Greedy Tino(双塔DP)
    POJ 2609 Ferry Loading(双塔DP)
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛十六进制转换成十进制
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13323021.html
Copyright © 2020-2023  润新知