hdu 5422:
题意:给出一个n个顶点,m条变的无向图,现在让你添加一条边,使1到n的最短路最短,并且在最短的情况下写出可以添加的边的不同数目。
思路:很简单,两种情况:1.如果1到n之间原来不存在边,那么我们添加的这一条边肯定是1~n,所以最短路一定是1,方法只有一种;2.如果1和n之间原来存在边,那么我们就随意连两个顶点即可,方法是n*(n-1)/2。
#include <iostream> #include <string> #include <cstring> #include <iostream> using namespace std; int g[200][200]; int main() { int n,m,a,b; while(cin>>n>>m) { memset(g,0,sizeof(g)); for(int i=1;i<=m;i++) { cin>>a>>b; g[a][b]=g[b][a]=1; } if(g[1][n]==0) cout<<1<<" "<<1<<endl; else cout<<1<<" "<<(n-1)*n/2<<endl; } return 0; }hdu 5423
经过画图分析,我们可以看出,除了最后一层的结点可以>=1,其他层的结点必须只有一个,否则同层的结点可以交换,例如:
1 1
2 3 和 2 3 就不符合特殊的树的要求,dfs再用map记录每一层的结点数即可。
4 5 5 4
#include <iostream> #include <string> #include <cstring> #include <iostream> #include <map> #include <set> using namespace std; int g[1003][1003]; int vis[1005]; map<int ,int> mp; int n,a,b; void dfs(int begina,int sum) { mp[sum]++; for(int i=1;i<=n;i++) { if(g[begina][i]&&!vis[i]) { vis[i]=1; dfs(i,sum+1); } } } int main() { while(cin>>n) { mp.clear(); memset(g,0,sizeof(g)); memset(vis,0,sizeof(vis)); for(int i=1;i<n;i++) { cin>>a>>b; g[a][b]=g[b][a]=1; } vis[1]=1; dfs(1,0); map<int,int>::iterator it; bool flag=true; for(it=mp.begin();it!=mp.end();++it) { if(it->second>1&&it->first!=mp.size()-1) { flag=false; break; } } if(flag) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
题意:给出n个点,n条边,问你是否存在哈密顿路(从一点出发,经过每一个点一次且仅有一次)
思路: 首先如果我们对每个点作为起点做dfs肯定会超时,这里我们发现,如果可以组成哈密顿路,那么会使用n-1条边,剩下的一条边有四种情况:
1.形成自环
2.连接首尾,这样每个点的度数都是2
3.连接除首尾的其他两个点,这样首尾的度数是1,我们随便找一个做起点dfs即可。
4.连接首尾中一个和其他点,还是会有一个度数是1的点,dfs即可
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int n,x,y,deg[1001]; bool flag,vis[1001],Map[1001][1001]; void dfs(int u,int sum) { if(flag) return ; if(sum==n){ flag=1; return; } for(int i=1;i<=n;++i) if(!vis[i]&&Map[u][i]) { vis[i]=1; dfs(i,sum+1); vis[i]=0; } } int main() { while(~scanf("%d",&n)) { flag=0; memset(deg,0,sizeof(deg)); memset(vis,0,sizeof(vis)); memset(Map,0,sizeof(Map)); for(int i=0;i<n;++i){ scanf("%d%d",&x,&y); if(x!=y&&!Map[x][y]) { Map[x][y]=Map[y][x]=1; ++deg[x],++deg[y]; } } int begina=1,tot=0; for(int i=1;i<=n;++i) { if(deg[i]==1) { begina=i; ++tot; } } if(tot>2) { puts("NO"); continue; } vis[begina]=1; dfs(begina,1); if(flag) puts("YES"); else puts("NO"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
BestCoder Round #53(hdu 5422&5423&5424)
原文地址:http://blog.csdn.net/nk_test/article/details/48094347