首先!這是個失敗的小程序,程序沒錯,可以達到預期目的。但是,時間,內存都超出了要求。懶,以後有時間我會改進的。
吝嗇的國度
時間限制:1000 ms | 內存限制:65535 KB
難度:3
-
描述
- 在一個吝嗇的國度裏有N個城市,這N個城市間只有N-1條路把這個N個城市連接起來。現在,Tom在第S號城市,他有張該國地圖,他想知道如果自己要去參觀第T號城市,必須經過的前一個城市是幾號城市(假設你不走重複的路)。
-
輸入
- 第一行輸入一個整數M表示測試數據共有M(1<=M<=5)組
每組測試數據的第一行輸入一個正整數N(1<=N<=100000)和一個正整數S(1<=S<=100000),N表示城市的總個數,S表示參觀者所在城市的編號
隨後的N-1行,每行有兩個正整數a,b(1<=a,b<=N),表示第a號城市和第b號城市之間有一條路連通。 -
輸出
- 每組測試數據輸N個正整數,其中,第i個數表示從S走到i號城市,必須要經過的上一個城市的編號。(其中i=S時,請輸出-1)
-
樣例輸入
-
1
10 1
1 9
1 8
8 10
10 3
8 6
1 2
10 4
9 5
3 7
-
樣例輸出
-
-1 1 10 10 9 8 3 1 1 8
這題目看起來就是一個搜尋的問題,容易想到廣度,深度搜什麼的。(而且題目中說到N個城市只有N-1條通路來連接,所以看成圖的話,應該就是極小連通子圖了吧)對於A和B之間有通路的話,我會用鄰接矩陣的1表示,不通則爲0.
下面的代碼隨便看看就好了,時間倉促,沒改進。(最後會給出較好的AC代碼)
#include<iostream>
using namespace std;
int map[100005][100005]; //用二維數組表示鄰接矩陣,這個地方很糟糕,會導致內存爆炸
int flag[100005]; //這個是用來記錄訪問過的城市
int pre; //pre是到達目的城市的先前城市
void findway(int v1,int v2,int N)
{
int i;
if(v1==v2)
{
pre=-1;
}
else
{
for(i=1;i<=N;i++)
{
if(map[v1][i]==1&&flag[i]==0)
{
if(i==v2)
{
pre=v1;
}
else
{
flag[v1]=1;
findway(i,v2,N);
flag[v1]=0; //這層遞歸出來後記得還原訪問過的城市,以免影響後續
}
}
}
}
}
int main()
{
int M,N,S,a,b;
int i,j,m,n;
cin>>M;
for(i=0;i<M;i++)
{
cin>>N>>S;
for(m=1;m<=N;m++)
for(n=1;n<=N;n++)
map[m][n]=0;
for(j=0;j<N-1;j++)
{
cin>>a>>b;
map[a][b]=1;
map[b][a]=1;
}
}
for(i=1;i<=N;i++)
{
findway(S,i,N);
cout<<pre<<" ";
flag[100005]=0;
}
cout<<endl;
return 0;
}
------------------------------------------------------------------------------------------分割--------------------------------------------------------
至於改進,可以使用容器,就是#include<vector>,vector是STL中最常見的容器,它是一種順序容器,支持隨機訪問。
vector是一塊連續分配的內存,從數據安排的角度來講,和數組極其相似, 不同的地方就是:數組是靜態分配空間,一旦分配了空間的大小,就不可再改變了; 而vector是動態分配空間,隨着元素的不斷插入,它會按照自身的一套機制不斷擴充自身的容量。關於它的用法可以詳細百度。
下面是http://blog.csdn.net/niushuai666/article/details/6670370的AC代碼,可以看看。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int pre[100005];
vector<int>v[100005];
void DFS(int cur)
{
for(int i = 0; i < v[cur].size(); ++i)
{
if(pre[v[cur][i]]) continue; //若存在父節點則繼續遍歷
pre[v[cur][i]] = cur; //相連節點的父節點爲cur
DFS(v[cur][i]); //深搜到底,把一條路上父節點全部找出
}
}
int main()
{
int ncase, num, cur, i, x, y;
scanf("%d", &ncase);
while(ncase--)
{
memset(v, 0, sizeof(v));
memset(pre, 0, sizeof(pre));
scanf("%d%d", &num, &cur);
pre[cur] = - 1; //起點沒有父節點
for(i = 0; i < num - 1; ++i)
{
scanf("%d%d", &x, &y);
v[x].push_back(y); //x與y相連
v[y].push_back(x); //y與x也肯定相連
}
DFS(cur); //起點開始深搜
for(i = 1; i <= num; ++i)
printf("%d ", pre[i]); //每個節點的父節點都保存在pri數組,輸出即可
}
return 0;
}