uva 10054 - The Necklace 惨痛经历

来源:互联网 发布:美墨战争 知乎 编辑:程序博客网 时间:2024/05/21 08:43

做了两天,一直在用bfs来做dfs的题,于是就一直TLE到死。以为邻接矩阵不够快,改用邻接表,但是还是TLE。直到怀疑服务器挂有问题= =,上网找别人的代码交。第一个找到的交上去还是错的,直到找到这个参考代码出处。

于是就仿照写一两次,终于发现了几处写错的地方。(其实是发现bfs和dfs的区别)


是什么:把每个珠子看出一条边,珠子的两种颜色看成点。就是给出所有的边(无向)看看能不能找到欧拉回路(就是一笔画,起点和终点同是一个点)(而起点和终点不在一个点上的一笔画就是欧拉道路)


为什么图的转换,把某些关系转化成边,点。解除是否存在什么什么的路径(方法),什么什么的最短路径(最优方法)。


怎么样要知道存在欧拉回路的图,不管从哪一个点出发,都能顺利完成“一笔画”(证明:既然能够一笔画完整个图而回到起点,那可以把图看成一个圆,那在圆上选任意一点都能完成一笔画)。所以判断是不是欧拉回路接下来输出路径就简单了(可对于我来说,并不是T_T)。

    而判断无向图是否为的欧拉回路有两个方面:

1,图是否联通的。

2,每个点的是否有偶数条边相连。

   第 1 点直接用并查集做。

   第 2 点在加入边时直接计算就是了。


以下是代码:

这是邻接矩阵的

#include<iostream>#include<cstdio>#include<string>#include<cstring>using namespace std;int fa[60];int data[60][60];int findfa(int i){if(fa[i]==i) return fa[i];fa[i]=findfa(fa[i]);return fa[i];}void eur(int k){for(int i=1;i<60;++i){if(data[k][i]){--data[k][i];--data[i][k];printf("%d %d\n",k,i);eur(i);//break;//这个不能加!}}}int main(){int cas;scanf("%d",&cas);for(int casi=1;casi<=cas;++casi){for(int i=0;i<60;++i)fa[i]=i;memset(data,0,sizeof(data));int n;scanf("%d",&n);int a,b;for(int i=0;i<n;++i){scanf("%d%d",&a,&b);int tmp=min(a,b);b=a+b-tmp;a=tmp;++data[a][b];++data[a][0]; //<span style="font-family: 'Microsoft YaHei';">计算和点连接的边的数量</span>++data[b][a];++data[b][0]; //也是<span style="font-family: 'Microsoft YaHei';">计算和点连接的边的数量</span>if(findfa(a)!=findfa(b))fa[findfa(b)]=findfa(a);}int flag=0,sta;for(int i=1;i<60;++i){if(data[i][0]%2) flag=1;if(data[i][0]) sta=i;}for(int i=1;i<60;++i)if(data[i][0]&&findfa(i)!=findfa(sta)) flag=1;printf("Case #%d\n",casi);if(flag){printf("some beads may be lost\n");if(casi!=cas) printf("\n");continue;}eur(sta);if(casi!=cas) printf("\n");}return 0;}

而这是邻接表写的

#include<iostream>#include<cstdio>#include<cstring>using  namespace std;struct node{int start,index;int tot;int upp;int fa;node(int i=0,int inndex=0){index=i;start=-1;upp=-1;tot=0;fa=inndex;}};node nda[110];struct edge{int next;int sta,end;int up;int use;edge(int a=0,int b=0,int c=0){sta=a;end=b;use=0;next=nda[a].start;nda[a].start=c;}};edge eda[16000];int find(int a){if(nda[a].fa==a) return a;nda[a].fa=find(nda[a].fa);return nda[a].fa;}void gotofind(int stain){for(int x=nda[stain].start;x!=-1;x=eda[x].next){if(eda[x].use==0){eda[x].use=1;eda[x^1].use=1;stain=eda[x].end;      //cout<<eda[x].sta<<' '<<eda[x].end<<endl;
                                                  /*
<span style="white-space:pre"></span>这个不能卸载递归前面,因为当递归结束回到这里输出的答案和题目要求不一样
<span style="white-space:pre"></span>可是又觉这样说不过去,不符合欧拉回路的性质啊。。。好纠结,知道的留个言~谢谢啦!
<span style="white-space:pre"></span>   */gotofind(stain);cout<<eda[x].end<<' '<<eda[x].sta<<endl;}}}int main(){int cas;cin>>cas;for(int casi=1;casi<=cas;++casi){for(int i=0;i<55;++i){node ini(0,i);nda[i]=ini;}int n;scanf("%d",&n);int maxin=-1;int ai,bi;int k=0,sum=0;for(int i=1;i<=n;++i){scanf("%d%d",&ai,&bi);edge tmp(ai,bi,k);eda[k]=tmp;++k;edge tmp1(bi,ai,k);eda[k]=tmp1;++k;++nda[ai].tot;++nda[bi].tot;maxin=max(maxin,ai);maxin=max(maxin,bi);int t1=find(nda[ai].fa),t2=find(nda[bi].fa);if(t1!=t2)nda[t1].fa=t2;++sum;}int flag=0,stain=0,maxto=-1;for(int i=1;i<=maxin;++i){if(maxto<nda[i].tot){maxto=nda[i].tot;stain=i;}if(nda[i].tot%2)flag=1;}int tfa=find(stain);for(int i=0;i<=55;++i){if(nda[i].tot&&tfa!=find(i)) flag=1;}cout<<"Case #"<<casi<<endl;if(flag){cout<<"some beads may be lost"<<endl;if(casi!=cas) cout<<endl;continue;}gotofind(stain);if(casi!=cas) cout<<endl;}return 0;}


关于dfs和bfs的应用区别(我的理解)是:

bfs:用于找最优

dfs:用于找有无

但是算法杀死很灵活的,并不是固定不变的。需要看情(xin)况(qing)使用





0 0