2020牛客暑期多校训练营(第二场) I Interval
思路:很明显最小割,但直接跑Dinic一定会超时,所以要将原图转化成对偶图来跑最短路,至于怎么转化,建议去搜其他人的博客。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <string>
#include <string.h>
#include <map>
#include <iostream>
// std::ios::sync_with_stdio(false);
// ios::sync_with_stdio(false);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
const int maxn = 3e6 + 50;
const LL mod = 998244353;
LL INF = 1e15;
#define fi first
#define se second
int n, m;
map<pii, int> mmap, mmap2;
struct Edge
{
int to, next;
LL w;
} edge[maxn];
int k, head[maxn];
void add(int a, int b, int w){
if(mmap2[{a, b}]) return ;
edge[k].to = b, edge[k].w = w, edge[k].next = head[a], head[a] = k++;
edge[k].to = a, edge[k].w = w, edge[k].next = head[b], head[b] = k++;
}
struct qnode
{
int u;
LL c;
bool operator < (const qnode &r) const{
return c > r.c;
}
};
priority_queue<qnode> que;
LL dis[maxn];
int vis[maxn];
void dj(int s, int t){
for(int i = 0; i <= t; i++) dis[i] = INF;
que.push({s, 0});
dis[s] = 0;
while(que.size()){
qnode tmp = que.top();
que.pop();
int u = tmp.u;
if(tmp.c != dis[u]) continue;
for(int i = head[u]; i != -1; i = edge[i].next){
int to = edge[i].to;
if(dis[to] > dis[u] + edge[i].w){
dis[to] = dis[u] + edge[i].w;
que.push({to, dis[to]});
}
}
}
if(dis[t] == INF) printf("-1\n");
else printf("%lld\n", dis[t]);
}
int main(int argc, char const *argv[])
{
scanf("%d%d", &n, &m);
LL sum = 0;
int s = 0, t = n * n * 10;
for(int i = 0; i <= t; i++){
head[i] = -1;
}
int cnt = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
mmap[{i, j}] = ++cnt;
}
}
for(int i = 1; i <= m; i++){
int le, ri;
LL c;
char ch;
scanf("%d%d %c%lld", &le, &ri, &ch, &c);
sum += c;
if(ch == 'L'){
if(ri == n) add(0, le * n + ri - 1, c);
else add(le * n + ri - 1, le * n + ri, c);
} else {
if(le == 1) add(le * n + ri - 1, t, c);
else add(le * n + ri - 1, (le - 1) * n + ri - 1, c);
}
}
dj(s, t);
return 0;
}