標籤:hdu bestcoder 題解 dfs
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;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
BestCoder Round #53(hdu 5422&5423&5424)