luogu P5292 [HNOI2019]校园旅行
生活随笔
收集整理的這篇文章主要介紹了
luogu P5292 [HNOI2019]校园旅行
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
首先考慮暴力M^2dp,考慮回文串是可以從回文中心每次在兩邊拓展的,設\(f_{i,j}\)為\(i\)到\(j\)的路徑是否是回文串,bfs轉移,枚舉兩點出邊,如果兩個新端點顏色相同就更新
然后這個大暴力可以優化到70',就是先枚舉一端的相鄰的點,然后注意到因為固定了那個相鄰的點,對應的另一個用來拓展的端點個數是\(O(n)\)的,然后轉移是\(O(m)\)的,所以總復雜度為\(O(nm)\)
然后考慮減少邊數.對于一個同色的連通塊,如果這個連通塊是二分圖,那么我們只要保留它的一個生成樹就好了,因為對于一端在上面的子路徑,在生成樹上可以使用反復橫跳走出同奇偶的子路徑(另一邊也同理),并且不會影響答案;如果不是二分圖,那么就有奇環,有奇環就可以改變路徑長度奇偶性,所以在生成樹上加一個自環就行了.然后對于每條邊兩端顏色不同的連通塊,顯然是二分圖,根據上面的道理,保留生成樹就行了.然后在新圖上跑dp,就是\(O(n^2)\)了
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<cmath> #include<ctime> #include<queue> #include<map> #include<set> #define LL long long #define db doubleusing namespace std; const int N=5000+10,M=500000+10; int rd() {int x=0,w=1;char ch=0;while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x*w; } struct graph {int to[M<<1],nt[M<<1],hd[N],tot;void add(int x,int y){++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;} }e,ee; int n,m,q,ff[N]; int findf(int x){return ff[x]==x?x:ff[x]=findf(ff[x]);} bool ng[N][N],co[N],inq[N],bg[N]; int vc[N]; char cc[N]; struct node {int x,y; }; queue<int> qq; queue<node> qu;int main() {e.tot=ee.tot=1;n=rd(),m=rd(),q=rd();scanf("%s",cc+1);for(int i=1;i<=n;++i) ff[i]=i,bg[i]=1,co[i]=cc[i]-'0',ng[i][i]=1,qu.push((node){i,i});for(int i=1;i<=m;++i){int x=rd(),y=rd();e.add(x,y);if(co[x]==co[y]) ff[findf(y)]=findf(x),ng[x][y]=ng[y][x]=1,qu.push((node){x,y});}memset(vc,-1,sizeof(vc));for(int i=1;i<=n;++i)if(findf(i)==i) inq[i]=1,qq.push(i);while(!qq.empty()){int x=qq.front();qq.pop();bool v0=0,v1=0;for(int i=e.hd[x];i;i=e.nt[i]){int y=e.to[i];if(co[x]!=co[y]) continue;if(inq[y]) v0|=!vc[y],v1|=vc[y];else vc[y]=!vc[x],ee.add(x,y),inq[y]=1,qq.push(y);}if(v0&&v1) bg[findf(x)]=0;}for(int i=1;i<=n;++i)if(findf(i)==i&&!bg[i]) ee.add(i,i);for(int i=1;i<=n;++i) ff[i]=i;for(int i=2;i<=e.tot;i+=2){int x=e.to[i],y=e.to[i^1];if(co[x]!=co[y]&&findf(x)!=findf(y)) ee.add(x,y),ff[findf(y)]=findf(x);}while(!qu.empty()){int x=qu.front().x,y=qu.front().y;qu.pop();for(int i=ee.hd[x];i;i=ee.nt[i]){int xx=ee.to[i];for(int j=ee.hd[y];j;j=ee.nt[j]){int yy=ee.to[j];if(co[xx]==co[yy]&&!ng[xx][yy]) ng[xx][yy]=ng[yy][xx]=1,qu.push((node){xx,yy});}}}while(q--) ng[rd()][rd()]?puts("YES"):puts("NO");return 0; }轉載于:https://www.cnblogs.com/smyjr/p/10712932.html
總結
以上是生活随笔為你收集整理的luogu P5292 [HNOI2019]校园旅行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 七、Oracle 数据库设计
- 下一篇: [AT2369] [agc013_c]