一開始按照自己的思路來。結果發現理解錯誤。題目說的是有多種可行方案時,選擇編號較小的street。我以爲每到一個節點,只能選擇與該結點連接的還未訪問過的編號最小的street。。。所以給的數據過了,還是WA。。。以下是錯誤代碼
這組數據能通過:
1 1 1
1 1 2
1 1 3
1 1 5
1 1 4
0 0
輸出:1 2 3 4 5
這組數據就通不過:
1 2 1
2 3 2
1 3 3
2 4 4
2 4 5
0 0
輸出:1 4 5 2 3
原因是到結點2的時候選擇了街道2而不是4,且沒有回溯的過程
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const unsigned MaxJunc = 45;
const unsigned MaxStreet = 2000;
typedef struct _JUNC
{
vector<unsigned> street;
}Junc;
int main()
{
Junc junc[MaxJunc];
unsigned street[MaxStreet][2];
unsigned streetCnt, maxJuncNum;
vector<unsigned> output;
unsigned x,y,z;
int i;
while(1)
{
memset(junc, 0, sizeof(struct _JUNC)*MaxJunc);
memset(street, 0, sizeof(unsigned)*MaxStreet*2);
streetCnt = 0;
maxJuncNum = 0;
cin>>x>>y;
if(x==0 && y==0)
break;
while(x!=0 && y!=0)
{
cin>>z;
junc[x].street.push_back(z);
junc[y].street.push_back(z);
street[z][0] = x;
street[z][1] = y;
++streetCnt;
if(x<y)
maxJuncNum = maxJuncNum>y?maxJuncNum:y;
else
maxJuncNum = maxJuncNum>x?maxJuncNum:x;
cin>>x>>y;
}
for(i=1; i<=maxJuncNum ; ++i)
{
vector<unsigned> tmp(junc[i].street.size());
if(junc[i].street.size())
{
for(int j=0; j<junc[i].street.size(); ++j)
tmp[j] = junc[i].street[j];
sort(tmp.begin(),tmp.end());
for(int j=0; j<junc[i].street.size();++j)
junc[i].street[j] = tmp[j];
}
}
i = 1;
while(junc[i].street.size())
{
unsigned j = 0;
unsigned visit;
for(;j<junc[i].street.size(); ++j)//找的從junc[i]出發將要去的下一條street
{
if(junc[i].street[j]!=0)
{
visit = junc[i].street[j];
junc[i].street[j] = 0;
break;
}
}
if(j==junc[i].street.size())
break;
output.push_back(visit);
i = (i==street[visit][0])?street[visit][1]:street[visit][0];//跳到當前訪問的street的另一端
for(unsigned k=0; k<junc[i].street.size(); ++k)//將另一端中對應的該條street置爲0
{
if(junc[i].street[k]==visit)
{
junc[i].street[k] = 0;
break;
}
}
}
if(output.size()!= streetCnt)
cout<<"Round trip does not exist."<<endl;
else
{
cout<<output[0];
for(i=1; i<output.size(); ++i)
cout<<" "<<output[i];
cout<<endl;
}
output.clear();
}
return 0;
}
參考別人的思路:http://blog.sina.com.cn/s/blog_48e3f9cd010002un.html 用遞歸
歐拉回路:對於一個圖可以從一個頂點沿着邊走下去,每個邊只走一次,所有的邊都經過後回到原點的路。一個無向圖存在歐拉回路的充要條件是每個頂點的度是偶數。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const unsigned MaxJunc = 45;
const unsigned MaxStreet = 1995;
unsigned graph[MaxJunc][MaxStreet];
unsigned stack[MaxStreet];
unsigned juncDegree[MaxJunc];//保存結點的度
bool hasVisited[MaxStreet];
unsigned top,maxStreetNo;
void Euler(int s)
{
int i;
for(i = 1; i <= maxStreetNo; i ++)
{
if(graph[s][i] && !hasVisited[i])
{
hasVisited[i] = true;
Euler(graph[s][i]);
stack[top ++] = i;
}
}
}
int main()
{
unsigned home;
unsigned x,y,z;
int i;
while(1)
{
memset(graph, 0, sizeof(unsigned)*MaxJunc*MaxStreet);
memset(stack, 0, sizeof(unsigned)*MaxStreet);
memset(juncDegree, 0, sizeof(unsigned)*MaxJunc);
memset(hasVisited, false, sizeof(bool)*MaxStreet);
maxStreetNo = 0;
top = 0;
cin>>x>>y;
home = min(x,y);
if(x==0 && y==0)
break;
while(x!=0 && y!=0)
{
cin>>z;
graph[x][z] = y;//x經過z到的y
juncDegree[x]++;//結點x的度加1
graph[y][z] = x;//y經過z到的x
juncDegree[y]++;//結點y的度加1
maxStreetNo = max(maxStreetNo, z);
cin>>x>>y;
}
for(i=1; i<MaxJunc; ++i)//判斷結點的度是否爲偶數
if(juncDegree[i]%2)
break;
if(i<MaxJunc)//有度不爲偶數的結點
{
cout<<"Round trip does not exist."<<endl;
}
else
{
Euler(home);
for(i = top - 1; i >= 0; i --)
cout<<stack[i]<<" ";
cout<<endl;
}
}
return 0;
}