BestCoder Round #53 (hdu 5422 & 5423 & 5424 ),
Hdu 5422:
Question: give n vertices and m-shaped undirected graphs. Now let you add an edge to minimize the shortest path between 1 and n, write the number of edges that can be added in the shortest possible condition.
Idea: Very simple, two cases: 1. If there is no edge between 1 and n, then the edge we add must be 1 ~ N, so the minimum short circuit must be 1. There is only one method; 2. if an edge exists between 1 and n, we can connect them to two vertices at will. The method is 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
Question: give you a tree and ask if you are a "special tree ". The definition of a special tree is that there is no different tree (the father with nodes is inconsistent) with him (the distance between each node and the root remains unchanged ).
After drawing analysis, we can see that except the last layer of nodes can be greater than or equal to 1, there must be only one node at the other layer, otherwise the nodes at the same layer can be exchanged, for example:
1 1
2 3 and 2 3 do not meet the requirements of special trees. dfs can record the knots of each layer with 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:
Question: give n vertices and n edges and ask if there is a Hamilton path (starting from one point, going through each vertex once and only once)
Idea: First, if we do dfs for each vertex as the starting point, it will definitely time out. Here we find that if we can form a Hamilton path, we will use n-1 edges, there are four cases for the remaining side:
1. forming a self-ring
2. Connect the beginning and end, so that the degree of each point is 2
3. Except the other two points at the beginning and end of the connection, so that the level at the beginning and end is 1. We can just find a start dfs.
4. If there is a point at the beginning and end of the connection and other points, there will still be a point with a level of 1, and dfs will be enough.
#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;}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.