洛谷 P2661 信息傳遞
阿新 • • 發佈:2017-11-09
empty 如何 div optimize 最小值 %d 需要 應該 floyed
這題好久前就做過了...結果過了幾個月還是不會...題解也看不懂...不過參考題解的一部分倒是懂了。
首先把每個人當做一個節點,從每個人向他要告訴的那個人連邊,產生一張有向圖。顯然,一個人如果不在環上,那麽就永遠不可能聽到自己的信息;一個人如果在環上,那麽就會在進行“包含這個點的長度最小的環的長度"輪之後聽到自己的信息。現在要求所有人聽到自己信息的輪數的最小值,也就是要求圖的最小環。
裸的最小環應該是floyed,$O(n^3)$。顯然是不行的。可以註意到一點,就是這題的圖中每個點最多只有一條出邊。那麽,一個點顯然不可能出現在多個環裏面。也就是說,一個點要麽不在環中,要麽只在一個單獨的環中。因此,可以先把不在環上的點去掉;對於每個環,只需要從環上任意一點出發dfs一遍求出回到自身路徑長度就行。
如何把不在環上的點去掉?可以用拓撲排序。拓撲排序做一遍只會留下環上點。
錯誤記錄:
1.deque不會用,47行寫成pop_back()
2.寫題過程中記錯題意,58行寫成max
1 //#pragma comment(linker, "/STACK:10240000,10240000") 2 #include<cstdio> 3 //#pragma GCC optimize (2) 4 #include<deque> 5 #include<malloc.h> 6 using namespace std; 7 struct E 8 {9 int to,nxt; 10 }e[400100]; 11 int f1[200100],ne,in[200100]; 12 deque<int> q; 13 bool boo[200100]; 14 int n,ans=0x3f3f3f3f; 15 int dfs(int x) 16 { 17 boo[x]=1; 18 // if(dep==43429) 19 // { 20 // printf("1"); 21 // } 22 for(int k=f1[x];k!=0;k=e[k].nxt) 23 if(!boo[e[k].to])24 return dfs(e[k].to)+1; 25 } 26 int main() 27 { 28 //int size = 256 << 20; // 256MB //windows上可能需要手動擴棧,不然會爆棧 29 //char *p = (char*)malloc(size) + size; 30 //__asm__("movl %0, %%esp\n" :: "r"(p)); 31 //freopen("testdata.in","r",stdin); 32 int i,a,t,k; 33 scanf("%d",&n); 34 for(i=1;i<=n;i++) 35 { 36 scanf("%d",&a); 37 e[++ne].to=a; 38 e[ne].nxt=f1[i]; 39 f1[i]=ne; 40 in[a]++; 41 } 42 for(i=1;i<=n;i++) 43 if(in[i]==0) 44 q.push_back(i); 45 while(!q.empty()) 46 { 47 t=q.front();q.pop_front(); 48 boo[t]=1; 49 for(k=f1[t];k!=0;k=e[k].nxt) 50 { 51 in[e[k].to]--; 52 if(in[e[k].to]==0) 53 q.push_back(e[k].to); 54 } 55 } 56 for(i=1;i<=n;i++) 57 if(!boo[i]) 58 ans=min(ans,dfs(i)+1); 59 printf("%d",ans); 60 return 0; 61 }
洛谷 P2661 信息傳遞