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; }