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;
}
hdu 5424:
题意:给出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;
}