上白泽慧音(tarjan,图的染色)
題目描述
在幻想鄉,上白澤慧音是以知識淵博聞名的老師。春雪異變導致人間之里的很多道路都被大雪堵塞,使有的學生不能順利地到達慧音所在的村莊。因此慧音決定換一個能夠聚集最多人數的村莊作為新的教學地點。人間之里由N個村莊(編號為1..N)和M條道路組成,道路分為兩種一種為單向通行的,一種為雙向通行的,分別用1和2來標記。如果存在由村莊A到達村莊B的通路,那么我們認為可以從村莊A到達村莊B,記為(A,B)。當(A,B)和(B,A)同時滿足時,我們認為A,B是絕對連通的,記為<A,B>。絕對連通區域是指一個村莊的集合,在這個集合中任意兩個村莊X,Y都滿足<X,Y>。現在你的任務是,找出最大的絕對連通區域,并將這個絕對連通區域的村莊按編號依次輸出。若存在兩個最大的,輸出字典序最小的,比如當存在1,3,4和2,5,6這兩個最大連通區域時,輸出的是1,3,4。
輸入輸出格式
輸入格式:
第1行:兩個正整數N,M
第2..M+1行:每行三個正整數a,b,t, t = 1表示存在從村莊a到b的單向道路,t = 2表示村莊a,b之間存在雙向通行的道路。保證每條道路只出現一次。
輸出格式:
第1行: 1個整數,表示最大的絕對連通區域包含的村莊個數。
第2行:若干個整數,依次輸出最大的絕對連通區域所包含的村莊編號。
思路:
顯然,有題可得,這是讓我們求一個面積最大的強連通分量
(如果有面積相同的情況,輸出字典序最小的)
我們自然可以用tarjan縮點
我們把舊點的點權當作1
這樣縮完后每個新點就是一個強連通分量,點權就是新點所代表的強連通分量的大小
我們縮完點后O(n)掃一邊所有新點,記下最大的點權
然后再按字典序O(n)掃一邊舊點,記下第一個所在新點點權為最大值的舊點所屬新點的編號
再按字典序O(n)掃一邊舊點,輸出所在新點為上一次操作記下的新點舊點即可
代碼:
// luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define rij register int j #define rii register int i using namespace std; int dq[5005],sum[5005],color[5005],tot,cnt,vis[5005]; int n,m,head[5005],last[5005],sta[5005],top,bnt; int dfn[5005],low[5005],ls[5005]; struct ljb{int to,nxt; }x[100005]; void add(int from,int to) {cnt++;x[cnt].to=to;if(head[from]==0){head[from]=cnt;}else{x[last[from]].nxt=cnt;}last[from]=cnt; } void tarjan(int wz) {top++;sta[top]=wz;bnt++;low[wz]=bnt;dfn[wz]=bnt;vis[wz]=1;for(rii=head[wz];i!=0;i=x[i].nxt){int ltt=x[i].to;if(dfn[ltt]==0){tarjan(ltt);low[wz]=min(low[wz],low[ltt]);}else{if(vis[ltt]!=0){low[wz]=min(low[wz],dfn[ltt]);}}}if(dfn[wz]==low[wz]){tot++;while(sta[top+1]!=wz){color[sta[top]]=tot;sum[tot]+=dq[sta[top]];vis[sta[top]]=0;top--;}} } int main() {scanf("%d%d",&n,&m);for(rii=1;i<=n;i++){dq[i]=1;}for(rii=1;i<=m;i++){int p,from,to;scanf("%d%d%d",&from,&to,&p);if(p==2){add(to,from);}add(from,to);}for(rii=1;i<=n;i++){if(dfn[i]==0){tarjan(i);}}int maxn=0;for(rii=1;i<=n;i++){int col=color[i];if(sum[col]>maxn){maxn=sum[col];}}cout<<maxn<<endl;int pd;for(rii=1;i<=n;i++){int col=color[i];if(sum[col]==maxn){pd=col;break;}}for(rii=1;i<=n;i++){if(color[i]==pd){printf("%d ",i);}} }?
轉載于:https://www.cnblogs.com/ztz11/p/9810745.html
總結
以上是生活随笔為你收集整理的上白泽慧音(tarjan,图的染色)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue 本地环境API代理设置和解决跨域
- 下一篇: shell 变量相关的命令