一题多解——Strategic Game
来源:互联网 发布:淘宝网保健品 编辑:程序博客网 时间:2024/06/15 13:48
点击打开题目
题目大意:给定一棵无根树,点亮其中某些点,使得这棵树的所有边都连接着一个以上的点亮的点
贪心中比较有挑战的题
由于如果点亮叶节点,就只会照亮一条边,但点亮它的父亲,就可以照亮除此边以外的更多的边,所以,可先将所有叶节点的父亲点亮
其余的点,则通过后序遍历来访问,如果它的所有儿子都点亮了,那它就不用点亮,反之则点亮它,最后在搜索出所有点亮的点的数量即可
代码如下:
#include <cstdio>#include<cmath>#include <cstring>#include <algorithm>using namespace std;int fir[3001],nxt[3001],to[3001],cnt;bool vis[1501],lt[1501];int getint(){ int num=0,flag=1;char c; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9')num=num*10+c-48,c=getchar(); return num*flag;}void newnote(int u,int v){to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}int n,ans;void dfs(int x){ int i; for(i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) { vis[to[i]]=1; dfs(to[i]); if(!lt[to[i]])lt[x]=1; }}int main(){ int i,j,x,y; while(scanf("%d",&n)==1) { ans=cnt=0; memset(fir,0,sizeof fir);memset(to,0,sizeof to);memset(nxt,0,sizeof nxt); memset(vis,0,sizeof vis);memset(lt,0,sizeof lt); for(i=1;i<=n;i++) { x=getint()+1;j=getint(); while(j--)y=getint()+1,newnote(x,y),newnote(y,x); } dfs(1); for(i=1;i<=n;i++)if(lt[i])ans++; printf("%d\n",ans); }}
如果没有yy到这种方法,树形DP也可以
设dp[root][0]
为没有点亮,dp[root][1]
为点亮
状态转移方程如下: dp[root][0]+=dp[son[root][i]][1];
dp[root][1]+=min(dp[son[root][i]][0],dp[son[root][i]][1]);
代码如下:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int dp[1501][2],son[1500][1500],fa[1501];int min(int x,int y){return x<y?x:y;}int getint(){ char c;int flag=1,num=0; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();} return num*=flag;}void work(int root){ int i; for(i=1;i<=son[root][0];i++) { work(son[root][i]); dp[root][0]+=dp[son[root][i]][1]; dp[root][1]+=min(dp[son[root][i]][0],dp[son[root][i]][1]); } dp[root][1]++;}int n;int main(){ int i,j,x,y,z; n=getint(); for(i=1;i<=n;i++) { x=getint(),x++,y=getint(); for(j=1;j<=y;j++) { z=getint(),z++; son[x][++son[x][0]]=z; fa[z]=x; } } for(i=1;i<=n;i++) if(!fa[i]) { work(i); printf("%d",min(dp[i][0],dp[i][1])); }}
DP也yy不到?看二分图匹配能不能救你
代码如下:
#include <cstdio>#include<cmath>#include <cstring>#include <algorithm>using namespace std;int fir[3001],nxt[3001],to[3001],cnt;bool vis[1501],vy[3001];int linky[3001],X[1501],g;int getint(){ int num=0,flag=1;char c; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9')num=num*10+c-48,c=getchar(); return num*flag;}void newnote(int u,int v){to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}int n,ans;void dfs(int u,int deep){ int i; if(deep&1)X[++g]=u; for(i=fir[u];i;i=nxt[i]) if(!vis[to[i]]) { vis[to[i]]=1; dfs(to[i],deep+1); }}bool xyl(int x){ int i; for(i=fir[x];i;i=nxt[i]) if(!vy[to[i]]) { vy[to[i]]=1; if(!linky[to[i]]||xyl(linky[to[i]])) { linky[to[i]]=x;return 1; } } return 0;}int main(){ int i,j,x,y; while(scanf("%d",&n)==1) { ans=cnt=g=0; memset(fir,0,sizeof fir);memset(to,0,sizeof to);memset(nxt,0,sizeof nxt); memset(vis,0,sizeof vis);memset(linky,0,sizeof linky); for(i=1;i<=n;i++) { x=getint()+1;j=getint(); while(j--)y=getint()+1,newnote(x,y),newnote(y,x); } vis[1]=1;dfs(1,1); for(i=1;i<=g;i++) { memset(vy,0,sizeof vy); ans+=xyl(X[i]); } printf("%d\n",ans); }}
阅读全文
2 0
- 一题多解——Strategic Game
- poj1463——Strategic game
- poj1463——strategic game
- POJ 1463——Strategic game
- HDU 1054——Strategic Game(树形DP)
- Strategic game
- Strategic game
- Strategic game
- Strategic Game
- Strategic game
- hdu1054——Strategic Game(最小顶点覆盖+邻接表)
- hdu1054 Strategic Game —— 二分图最大匹配 or 树形dp
- poj1463 Strategic game
- hdoj 1054 Strategic Game
- hdu 1054 Strategic Game
- HDU 1054 Strategic Game
- hdu 1054 Strategic Game
- hdu 1054 Strategic Game
- mybatis 学习笔记
- USACO-section1.5 Superprime Rib[深搜]
- Java基础笔记之一
- flex布局完全入门教程
- Neutron 默认安全组规则
- 一题多解——Strategic Game
- 51nod 1461 稳定桌
- 关于TRIM的优化技巧
- 【转载】String,StringBufffer之间的区别以及StringBuffer总结
- 最大子数组 II
- ActiveMQ的集群
- scikit-image/matplotlib处理图像知识点 2017 7.15
- js阻止form表单提交
- E