新牛到部隊, CG 要求它們天天早上搞晨跑,從A農場跑到B農場。從A農場到B農場中有n-2個路口,分別標上號,A農場爲1號, B農場爲n號,路口分別爲 2 ..n -1 號,從A農場到B農場有不少條路徑能夠到達,而CG發現有的路口是必須通過的,即每條路徑都通過的路口,CG要把它們記錄下來,這樣CG就能夠先到那個路口,觀察新牛們有沒有偷懶,而你的任務就是找出全部必經路口。數組
輸入格式:spa
第一行兩個用空格隔開的整數 n ( 3<=n<=2000 )和e ( 1<=e<= 8000 )。code
接下來從第2到第e + 1行,每行兩個用空格隔開的整數p和q,表示路口p和q之間有路徑直達。blog
輸入數據保證必經路口必定存在,而且每一個路口都和A農場、B農場相連通。io
輸出格式:class
第一行一個整數m,表示必經路口的數目。搜索
第二行按從小到大的順序依次輸出每一個必經路口的編號,每兩個數之間用一個空格隔開。next
6 6 1 2 2 4 2 3 3 5 4 5 5 6
2 2 5
思路:就按照題目中的樣子來模擬就好。
把除了起點和終點之外的全部點都試着刪除一下,看看可否走到終點,若是能走到,則這個點必定不是必經點,反之則是必經點。
代碼以下:
1 #include <stdio.h> 2 int cnt=0; 3 int head[20000]={0};//表頭數組 4 int flag=0;//1表示能走到終點,0表示不能 5 int ans[20002]={0};//記錄答案數組 6 int n,e;//點、邊 7 int temp[20002]={0};//離線記錄須要刪除的點 8 struct Edge//領接表存儲類型 9 { 10 int next,to; 11 }edge[16002];//必定要大點!!應該是邊數的兩倍多一點!! 12 13 void add(int x,int y)//添加邊 14 { 15 cnt++; 16 edge[cnt].next=head[x]; 17 edge[cnt].to=y; 18 head[x]=cnt; 19 } 20 21 void dfs(int start,int del) 22 { 23 if(start==n)//搜到了終點,不是必經點 24 { 25 flag=1; 26 return ; 27 } 28 temp[start]=del;//離線記錄須要刪除的點 29 for(int i=head[start];i!=0;i=edge[i].next)//從start開始,每次搜索start所鏈接的點 30 { 31 int y=edge[i].to;//start所鏈接的點 32 if(temp[y]!=del&&y!=del) dfs(y,del);//若是走到的店點不是暫時刪除的點,往下搜索,更新start爲y 33 } 34 } 35 36 int main() 37 { 38 int p,q; 39 int i; 40 int ans[20002]={0};//記錄答案 41 scanf("%d%d",&n,&e); 42 for(i=1;i<=e;i++)//添加無向圖 43 { 44 scanf("%d%d",&p,&q); 45 add(p,q); 46 add(q,p); 47 } 48 cnt=0;//記錄答案數目 49 for(i=2;i<n;i++) 50 { 51 flag=0; 52 dfs(1,i);//從1號節點開始跑,依次刪除編號爲i的節點 53 if(flag==0)//若是i是必經點 54 { 55 cnt++; 56 ans[cnt]=i; 57 } 58 } 59 /*============================*///輸出答案 60 printf("%d\n",cnt); 61 for(i=1;i<=cnt;i++) 62 { 63 printf("%d ",ans[i]); 64 } 65 printf("\n"); 66 /*============================*///輸出答案 67 return 0; 68 }