//题意:就是你需要派最少的士兵来巡查每一条边。相当于求最少点覆盖,用最少的点将所有边都覆盖掉
//题解:
//因为这是一棵树,所以对于每一条边的两个端点,肯定要至少有一个点需要放入士兵,那么对于x->y这一条边
//dp[x][0]=0 表示在x这一点上不放人士兵
//dp[x][1]=1 表示在x这一个点上放入士兵
//那么就有
//dp[x][0]+=dp[y][1];
//dp[x][1]+=min(dp[y][0],dp[y][1]);
//注意这一道题不需要建立一个图,然后再去dfs,因为题目上就是按树从根到叶逐渐给出的。所以可以直接存
//belong用来表示每一个点的层数,pre表示它的父亲节点
第一次我是建了一个图去找dp,然后就MLE了
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=1500; 7 struct edge 8 { 9 int v,next; 10 }e[maxn]; 11 int cnt,head[maxn],dp[maxn][5]; 12 void add_edge(int x,int y) 13 { 14 e[cnt].v=y; 15 e[cnt].next=head[x]; 16 head[x]=cnt++; 17 } 18 int n; 19 void dfs(int x,int pre) 20 { 21 dp[x][0]=0; 22 dp[x][1]=1; 23 for(int i=head[x];i!=-1;i=e[i].next) 24 { 25 int to=e[i].v; 26 //printf("%d %d\n",x,to); 27 if(to==pre) 28 { 29 //printf("**%d**%d\n",x,to); 30 continue; 31 } 32 dfs(to,x); 33 dp[x][0]+=dp[to][1]; 34 dp[x][1]+=min(dp[to][1],dp[to][0]); 35 } 36 } 37 int main() 38 { 39 while(~scanf("%d",&n)) 40 { 41 memset(head,-1,sizeof(head)); 42 cnt=0; 43 memset(dp,0,sizeof(dp)); 44 int x,y,sum,u,flag=0; 45 for(int i=1;i<=n;++i) 46 { 47 scanf("%d:(%d)",&x,&sum); 48 49 x++; 50 if(flag==0) 51 { 52 flag=1; 53 u=x; 54 } 55 while(sum--) 56 { 57 scanf("%d",&y); 58 y++; 59 add_edge(x,y); 60 add_edge(y,x); 61 } 62 } 63 //printf("%d**\n",u); 64 dfs(u,u); 65 printf("%d\n",min(dp[u][0],dp[u][1])); 66 } 67 return 0; 68 }View Code
正解:
1 //题意:就是你需要派最少的士兵来巡查每一条边。相当于求最少点覆盖,用最少的点将所有边都覆盖掉 2 //题解: 3 //因为这是一棵树,所以对于每一条边的两个端点,肯定要至少有一个点需要放入士兵,那么对于x->y这一条边 4 //dp[x][0]=0 表示在x这一点上不放人士兵 5 //dp[x][1]=1 表示在x这一个点上放入士兵 6 //那么就有 7 //dp[x][0]+=dp[y][1]; 8 //dp[x][1]+=min(dp[y][0],dp[y][1]); 9 10 //注意这一道题不需要建立一个图,然后再去dfs,因为题目上就是按树从根到叶逐渐给出的。所以可以直接存 11 //belong用来表示每一个点的层数,pre表示它的父亲节点 12 #include<stdio.h> 13 #include<string.h> 14 #include<iostream> 15 #include<algorithm> 16 using namespace std; 17 const int maxn=1505; 18 int belong[maxn],pre[maxn],dp[maxn][5],cnt; 19 int n; 20 void DP(int x,int index) 21 { 22 dp[x][0]=0; 23 dp[x][1]=1; 24 for(int i=1;i<=n;++i) 25 { 26 if(pre[i]==x) 27 { 28 DP(i,index+1); 29 dp[x][0]+=dp[i][1]; 30 dp[x][1]+=min(dp[i][0],dp[i][1]); 31 } 32 } 33 } 34 int main() 35 { 36 while(~scanf("%d",&n)) 37 { 38 memset(pre,0,sizeof(pre)); 39 memset(dp,0,sizeof(dp)); 40 memset(belong,0,sizeof(belong)); 41 cnt=0; 42 int x,y,sum,u,flag=0; 43 for(int i=1;i<=n;++i) 44 { 45 scanf("%d:(%d)",&x,&sum); 46 x++; 47 belong[x]=++cnt; 48 if(flag==0) 49 { 50 flag=1; 51 u=x; 52 } 53 cnt++; 54 while(sum--) 55 { 56 scanf("%d",&y); 57 y++; 58 pre[y]=x; 59 // add_edge(x,y); 60 // add_edge(y,x); 61 belong[y]=cnt; 62 } 63 } 64 pre[u]=-1; 65 DP(u,1); 66 printf("%d\n",min(dp[u][0],dp[u][1])); 67 } 68 return 0; 69 }View Code