Intervalnode
题解将每一个区间看作二维平面上的点,咱们的目标就是阻止从\((1,n)\)走到任意一个\((x,x)\)
显然相邻的点能够连边,咱们把\((1,n)\)看作源点的话,新建一个汇点将全部\((x,x)\)连向汇点,那么这就是一个最小割问题
可是会T。
发现这是一个平面图,转化为对偶图的最短路便可ios
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<cmath> #include<map> #include<set> #define LL long long int #define REP(i,n) for (int i = 1; i <= (n); i++) #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define cls(s,v) memset(s,v,sizeof(s)) #define mp(a,b) make_pair<int,int>(a,b) #define cp pair<int,int> using namespace std; const int maxn = 250005,maxm = 100005; const LL INF = 1000000000000000000ll; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();} while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();} return flag ? out : -out; } int h[maxn],ne; struct EDGE{ int to,w,nxt; }ed[maxn * 2]; void build(int u,int v,int w){ ed[++ne] = (EDGE){v,w,h[u]}; h[u] = ne; ed[++ne] = (EDGE){u,w,h[v]}; h[v] = ne; //printf("build %d to %d costs %d\n",u,v,w); } int C[505][505],R[505][505]; int n,m,S,T; int id(int x,int y){ return x * (x - 1) / 2 + y; } LL d[maxn],vis[maxn]; struct node{int u; LL d;}; inline bool operator <(const node& a,const node& b){return a.d > b.d;} priority_queue<node> q; void dijkstra(){ for (int i = 1; i <= T; i++) d[i] = INF,vis[i] = false; d[S] = 0; node u; q.push((node){S,d[S]}); while (!q.empty()){ u = q.top(); q.pop(); if (vis[u.u]) continue; vis[u.u] = true; Redge(u.u) if (!vis[to = ed[k].to] && d[to] > d[u.u] + ed[k].w){ d[to] = d[u.u] + ed[k].w; q.push((node){to,d[to]}); } } } int main(){ n = read(); m = read(); int l,r,w; char c; for (int i = 1; i <= m; i++){ l = read(); r = read(); scanf("%c",&c); w = read(); if (c == 'L') R[l][r] = w; else C[l][r] = w; } for (int i = 1; i <= n - 1; i++) for (int j = 1; j <= i; j++){ //puts("LXT"); //printf("[%d,%d] [%d,%d]\n",i + 1,j + 1,i + 1,j); //cout << C[i + 1][j + 1] << ' ' << R[i + 1][j] << endl; if (j < i && C[j + 1][i + 1]) build(id(i,j),id(i,j + 1),C[j + 1][i + 1]); if (i < n - 1 && R[j][i + 1]) build(id(i,j),id(i + 1,j),R[j][i + 1]); } S = 0; T = n * (n - 1) / 2 + 1; for (int i = 1; i <= n - 1; i++) if (C[1][i + 1]) build(S,id(i,1),C[1][i + 1]); for (int i = 1; i <= n - 1; i++) if (R[i][n]) build(id(n - 1,i),T,R[i][n]); dijkstra(); if (d[T] != INF) printf("%lld\n",d[T]); else puts("-1"); return 0; }