【2020牛客多校第二场】I Interval

I 题 Interval

原题:

image-20201021133652787

思路

打的时候一看有区间操作想都没想,就觉得肯定是特别nb的数据结构|dp,结果...打脸,都是前面一堆数学题搞我心态(强行甩锅)

才发现就是网络流(对偶图)的模板题😂 网络流能让你看出来就不会是网络流了

大概思想就是把一个区间(l,r)看成坐标上的点,每次操作就是在点与点之间连边,求最小割。

但是nm这么大肯定过不了,so套路就来了(建对偶图求最短路)

可以参考 洛谷的狼捉🐇 这题照理说应该比Interval更难(早知道就不用dinic水这题了)

补充:
以下都是自己yy,说的不对可以忽略,不喜勿喷
可能有些人总是很好奇源点,汇点要怎么连边确定(怎么一下左上全连,一下...)
我认为既然本质是你要切掉一些边,你就一定会有进边和出边,可以从哪进去就连源点,可以从哪出来就连汇点。
(但是一定要保证连接进边和出边的一条路可以把图'切断')

比如这题,画图后会发现上边连的是源点,右边是汇点,因为这样无论怎么走都可以把 点 (1,n)'切出来'虽然我还没试其他的连边方法

代码

不会有人对偶图会建成和我一样的吧,不会吧,不会吧🐶

#include<bits/stdc++.h>
using namespace std;
const int N = 502 * 502;
const long long inf = 0x3f3f3f3f3f3f3f3f;
int n, m, qx, zx;
long long dis[N];
bool use[N];
struct node
{
    int link;
    long long w;
    bool operator < (const node &qq) const{
        return qq.w < w;
    }
};

vector<node> f[N];
priority_queue<node> q;

void add_edge(int u,int v,long long w)
{
    f[u].push_back((node){v, w});
    f[v].push_back((node){u, w});
}
void dij()
{
    for (int i= qx; i <= zx;i++)
        dis[i] = inf;
    dis[qx] = 0;
    q.push((node){qx,0});
    while (!q.empty())
    {
        node temp = q.top();
        q.pop();
        if(use[temp.link])
            continue;
        use[temp.link] = 1;
        for(auto i:f[temp.link])
        {
            if(dis[i.link]>=dis[temp.link]+i.w)
            {
                dis[i.link] = dis[temp.link] + i.w;
                q.push((node){i.link,dis[i.link]});
            }
        }
    }
    
}
int main()
{
    scanf("%d %d", &n,&m);
    qx = 0;
    zx = n * n + 1;
    for (int i = 1; i <= m;i++)
    {
        int a, b,d;
        char c[4];
        scanf("%d %d %s %d", &a, &b, c, &d);
        if(c[0]=='L')
        {
            if(b==n)
            {
                add_edge((a - 1) * (n - 1) + b-1, zx,d);
            }
            else
            {
                add_edge((a - 1) * (n - 1) + b - 1, (a - 1) * (n - 1) + b,d);
            }
        }
        else
        {
            if(a==1)
            {
                add_edge((a - 1) * (n - 1) + b - 1, qx, d);
            }
            else
            {
                add_edge((a - 1) * (n - 1) + b - 1, (a - 2)* (n - 1) + b - 1, d);
            }
        }
    }
    // for (int i = 1; i <= n * n;i++)
    // {
    //     printf("i:%d\n", i);
    //     for(auto j:f[i])
    //     {
    //         printf("%d ", j.link);
    //     }
    //     printf("\n");
    // }
    dij();
    if(dis[zx]!=inf)
        printf("%lld\n", dis[zx]);
    else
        printf("-1\n");
    return 0;
}
/*

*/
posted @ 2020-07-15 19:54  Sakura_Momoko  阅读(272)  评论(0编辑  收藏  举报