题目链接:http://codeforces.com/problemset/problem/350/B
一开始想复杂了,建了张图,结果效率太低T了。其实用数组存可以了,结果发现的时候快没时间了,修改好前5分钟比赛就结束了,泪目。。。
题目大意:每个地点有用1表示旅馆,用0表示是山地。每个地点用一个数表示能从哪一个地点到达这里(单向)。现在要求一条最长的路径,除了终点为旅馆外,前面的路径上都是山地。要求前面的路上不能有分岔路,即从该点出发只有一条可行路。
解题思路:开一个数组存到达该点的始发地,再开一个数组存以某点为起点的路径有几条,不为1即可删去不计。然后从每一个旅馆开始向前深搜,找出最长的路径。

1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 #define N 100005 8 #define M 200010 9 int ob[N],ro[N]; 10 int hotel[N],K,road[N],road2[N];//hotel记录每个旅馆的位置,road存最长路径 11 int v[N],link[N];//v记录到达该点的始发地,link记录以每一个点为起点有多少条路径 12 void dfs(int now ,int num)//now表示搜到了哪一个,num表示加上该点路径有多长 13 { 14 int i,k; 15 if(link[now]>1) 16 { 17 return; 18 } 19 road2[num-1]=now; 20 if(K<num&&(link[v[now]]>1||v[now]==0))//当搜到下一个点有超过一条路径,或者连接该点的是一条无效路径时可更新最大值 21 { 22 K=num; 23 for(i=0;i<K;i++) 24 road[i]=road2[i]; 25 } 26 if(v[now]&&link[v[now]]<=1) 27 dfs(v[now],num+1); 28 } 29 int main() 30 { 31 memset(link,0,sizeof(link)); 32 int n,i,cnt=0,e=0; 33 scanf("%d",&n); 34 for(i=1;i<=n;i++) 35 { 36 scanf("%d",&ob[i]); 37 if(ob[i]==1) 38 hotel[cnt++]=i; 39 } 40 for(i=1;i<=n;i++) 41 { 42 scanf("%d",&ro[i]); 43 if(ro[i]){ 44 v[i]=ro[i]; 45 link[ro[i]]+=1; 46 } 47 } 48 for(i=0;i<cnt;i++) 49 { 50 if(K==0) 51 { 52 K=1; 53 road[0]=hotel[i]; 54 } 55 dfs(hotel[i],1); 56 } 57 printf("%d ",K); 58 for(i=K-1;i>=0;i--) 59 { 60 if(i) 61 printf("%d ",road[i]); 62 else 63 printf("%d",road[i]); 64 } 65 printf(" "); 66 return 0; 67 }