樹形dp poj1463

題意就是設置最少的哨兵,可以看到全部的路。ios

二分圖也能解決,即二分圖最小點覆蓋 用vector超內存了,ide

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 #define MAXN 1600
 6 #define MAXE 300000
 7 struct Edge
 8 {
 9     int v; // 
10     int next;
11 }edge[MAXE];
12 int head[MAXN]; // 每一個點臨接的邊
13 int cnt ; // 邊的條數
14 int n ; // 點的個數
15 int path[MAXN];
16 bool used[MAXN];
17 void add(int u,int v)
18 {
19     edge[cnt].v = v;
20     edge[cnt].next = head[u];
21     head[u] = cnt++;
22 
23     edge[cnt].v = u;
24     edge[cnt].next = head[v];
25     head[v] = cnt++;
26 }
27 bool dfs(int u)
28 {
29     for(int i = head[u]; i != -1; i = edge[i].next)
30     {
31         int v = edge[i].v;
32         if(!used[v])
33         {
34             used[v] = true;
35             if(path[v] == -1 || dfs(path[v]))
36             {
37                 path[v] = u;
38                 return true;
39             }
40         }
41     }
42     return false;
43 }
44 int match()
45 {
46     int res = 0;
47     memset(path,-1,sizeof(path));
48     for(int u = 0; u < n; u++)
49     {
50         memset(used,0,sizeof(used));
51         if(dfs(u))
52             res++;
53     }
54     return res;
55 }
56 int main()
57 {
58     //freopen("Input.txt","r",stdin);
59     while(scanf("%d",&n) != EOF)
60     {
61         memset(edge,0,sizeof(edge));
62         memset(head,-1,sizeof(head));
63         cnt = 0;
64         for(int i = 0; i < n; i++)
65         {
66             int a,b,c;
67             scanf("%d:(%d)",&a,&b);
68             while(b--)
69             {
70                scanf("%d",&c);
71                add(a,c);
72             }
73         }
74         cout<<match()/2<<endl;
75     }
76     return 0;
77 }
代碼

用樹形dp求解即,每一個點都有設哨兵和不設哨兵。dp1爲設置哨兵,dp2爲不設置哨兵。spa

則  dp1【s】 + =min(dp1【x】,dp2【x】);//s爲父節點,x爲子節點。 code

   dp2【s】 + = sum{  dp1【x】}; 父節點不設置哨兵,則其子節點都要設置哨兵。blog

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 using namespace std;
 6 vector<int>V[1500];
 7 int vis[1500];
 8 int dp1[1500],dp2[1500];//設和不設
 9 void init()
10 {
11     for(int i=0;i<1500;i++)
12     {
13         V[i].clear();
14         dp1[i]=1;
15         dp2[i]=0;
16     }
17     memset(vis,0,sizeof(vis));
18 }
19 void dfs(int s)
20 {
21     vis[s]=1;
22     for(int i=0;i<(int)V[s].size();i++)
23     {
24         int x=V[s][i];
25         if(!vis[x])
26         {
27             dfs(x);
28             dp2[s]+=dp1[x];
29             dp1[s]+=min(dp1[x],dp2[x]);
30         }
31     }
32 }
33 int main()
34 {
35     //freopen("Input.txt","r",stdin);
36     int n,i,j,k,x;
37     while(~scanf("%d",&n))
38     {
39         init();
40         for(i=1;i<=n;i++)
41         {
42             scanf("%d:(%d)",&j,&k);
43             while(k--)
44             {
45                 scanf("%d",&x);
46                 V[j].push_back(x);
47                 V[x].push_back(j);
48             }
49         }
50         dfs(0);
51         printf("%d\n",min(dp1[0],dp2[0]));
52     }
53     return 0;
54 }
代碼
相關文章
相關標籤/搜索