• 【DFS求树的最大二分匹配+输入外挂】HDU 6178 Monkeys


    http://acm.hdu.edu.cn/showproblem.php?pid=6178

    【题意】

    • 给定一棵有n个结点的树,现在有k个猴子分布在k个结点上,我们可以删去树上的一些边,使得k个猴子每个猴子都至少和其他一个猴子相连
    • 问树上最少保留多少条边

    【思路】

    • 每个猴子要至少和一个猴子相连,考虑保留的边最少,那么最优的情况一定是一条边的两个顶点放两个猴子,这些边的顶点都不重合
    • 我们现在要找到给定的树中最多有多少条这样的边,即最大二分匹配
    • O(n)的DFS,对于每个结点,优先与叶子结点形成一条边

    【AC】

      1 #include<bits/stdc++.h>
      2 using namespace std; 
      3 typedef long long ll;
      4 namespace IO
      5 {
      6     const int MX=1e8;
      7     char buf[MX];
      8     int c,sz;
      9     void begin()
     10     {
     11         c=0;
     12         sz=fread(buf,1,MX,stdin);
     13     }
     14     inline bool read(int &x)
     15     {
     16         while(c<sz && buf[c]!='-' && (buf[c]<'0'||buf[c]>'9')) ++c;
     17         if(c>=sz) return false;
     18         bool flag=0;
     19         if(buf[c]=='-') flag=1,++c;
     20         for(x=0;c<sz&&buf[c]>='0'&&buf[c]<='9';++c)
     21             x=x*10+buf[c]-'0';
     22         if(flag) x=-x;
     23         return true;
     24     }
     25 }
     26 
     27 int n,k;
     28 const int maxn=1e5+2;
     29 const int maxm=maxn*2;
     30 bool vis[maxn];
     31 struct edge
     32 {
     33     int to;
     34     int nxt;
     35 }e[maxm];
     36 int head[maxn];
     37 int tot;
     38 //int dp[maxn][2];
     39 int flag;
     40 int cnt;
     41 void init()
     42 {
     43     memset(head,-1,sizeof(head));
     44     tot=0;
     45   //  memset(dp,0,sizeof(dp));
     46       memset(vis,false,sizeof(vis));
     47       cnt=0;
     48 }
     49 void addedge(int u,int v)
     50 {
     51     e[tot].to=v;
     52     e[tot].nxt=head[u];
     53     head[u]=tot++;
     54 }
     55 
     56 void dfs(int u,int pa)
     57 {
     58     for(int i=head[u];i!=-1;i=e[i].nxt)
     59     {
     60         int v=e[i].to;
     61         if(v==pa) continue;
     62         dfs(v,u);
     63         if(!vis[u]&&!vis[v])
     64         {
     65             cnt++;
     66             vis[u]=vis[v]=true;
     67         }
     68     }
     69 }
     70 int main()
     71 {
     72     IO::begin();
     73     int T;
     74       IO::read(T);
     75    // scanf("%d",&T);
     76     while(T--)
     77     {
     78         init();
     79       //  scanf("%d%d",&n,&k);
     80         IO::read(n);IO::read(k);
     81         int x;
     82         for(int i=2;i<=n;i++)
     83         {
     84             //scanf("%d",&x);
     85             IO::read(x);
     86             addedge(i,x);
     87             addedge(x,i);
     88         }
     89         dfs(1,-1);
     90         int tmp=cnt*2;
     91         int ans;
     92         if(k<=tmp)
     93         {
     94             ans=k/2;
     95             if(k%2) ans++;
     96         }
     97         else
     98         {
     99             ans=cnt+k-tmp;
    100         }
    101         printf("%d
    ",ans);
    102     }
    103     return 0;
    104 }
    贪心,优先选叶子结点
      1 #include<bits/stdc++.h>
      2 namespace fastIO {
      3 #define BUF_SIZE 1100000
      4 #define OUT_SIZE 1100000
      5 #define ll long long
      6 // fread->read
      7 bool IOerror = 0;
      8 inline char nc() {
      9     static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
     10     if (p1 == pend) {
     11         p1 = buf;
     12         pend = buf + fread(buf, 1, BUF_SIZE, stdin);
     13         if (pend == p1) {
     14             IOerror = 1;
     15             return -1;
     16         }
     17         //{printf("IO error!
    ");system("pause");for (;;);exit(0);}
     18     }
     19     return *p1++;
     20 }
     21 inline bool blank(char ch) {
     22     return ch == ' ' || ch == '
    ' || ch == '
    ' || ch == '	';
     23 }
     24 inline void read(int &x) {
     25     bool sign = 0;
     26     char ch = nc();
     27     x = 0;
     28     for (; blank(ch); ch = nc())
     29         ;
     30     if (IOerror) return;
     31     if (ch == '-') sign = 1, ch = nc();
     32     for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
     33     if (sign) x = -x;
     34 }
     35 inline void read(ll &x) {
     36     bool sign = 0;
     37     char ch = nc();
     38     x = 0;
     39     for (; blank(ch); ch = nc())
     40         ;
     41     if (IOerror) return;
     42     if (ch == '-') sign = 1, ch = nc();
     43     for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
     44     if (sign) x = -x;
     45 }
     46 inline void read(double &x) {
     47     bool sign = 0;
     48     char ch = nc();
     49     x = 0;
     50     for (; blank(ch); ch = nc())
     51         ;
     52     if (IOerror) return;
     53     if (ch == '-') sign = 1, ch = nc();
     54     for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
     55     if (ch == '.') {
     56         double tmp = 1;
     57         ch = nc();
     58         for (; ch >= '0' && ch <= '9'; ch = nc()) tmp /= 10.0, x += tmp * (ch - '0');
     59     }
     60     if (sign) x = -x;
     61 }
     62 inline void read(char *s) {
     63     char ch = nc();
     64     for (; blank(ch); ch = nc())
     65         ;
     66     if (IOerror) return;
     67     for (; !blank(ch) && !IOerror; ch = nc()) *s++ = ch;
     68     *s = 0;
     69 }
     70 inline void read(char &c) {
     71     for (c = nc(); blank(c); c = nc())
     72         ;
     73     if (IOerror) {
     74         c = -1;
     75         return;
     76     }
     77 }
     78 // getchar->read
     79 inline void read1(int &x) {
     80     char ch;
     81     int bo = 0;
     82     x = 0;
     83     for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
     84         if (ch == '-') bo = 1;
     85     for (; ch >= '0' && ch <= '9'; x = x * 10 + ch - '0', ch = getchar())
     86         ;
     87     if (bo) x = -x;
     88 }
     89 inline void read1(ll &x) {
     90     char ch;
     91     int bo = 0;
     92     x = 0;
     93     for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
     94         if (ch == '-') bo = 1;
     95     for (; ch >= '0' && ch <= '9'; x = x * 10 + ch - '0', ch = getchar())
     96         ;
     97     if (bo) x = -x;
     98 }
     99 inline void read1(double &x) {
    100     char ch;
    101     int bo = 0;
    102     x = 0;
    103     for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
    104         if (ch == '-') bo = 1;
    105     for (; ch >= '0' && ch <= '9'; x = x * 10 + ch - '0', ch = getchar())
    106         ;
    107     if (ch == '.') {
    108         double tmp = 1;
    109         for (ch = getchar(); ch >= '0' && ch <= '9'; tmp /= 10.0, x += tmp * (ch - '0'), ch = getchar())
    110             ;
    111     }
    112     if (bo) x = -x;
    113 }
    114 inline void read1(char *s) {
    115     char ch = getchar();
    116     for (; blank(ch); ch = getchar())
    117         ;
    118     for (; !blank(ch); ch = getchar()) *s++ = ch;
    119     *s = 0;
    120 }
    121 inline void read1(char &c) {
    122     for (c = getchar(); blank(c); c = getchar())
    123         ;
    124 }
    125 // scanf->read
    126 inline void read2(int &x) {
    127     scanf("%d", &x);
    128 }
    129 inline void read2(ll &x) {
    130 #ifdef _WIN32
    131     scanf("%I64d", &x);
    132 #else
    133 #ifdef __linux
    134     scanf("%lld", &x);
    135 #else
    136     puts("error:can't recognize the system!");
    137 #endif
    138 #endif
    139 }
    140 inline void read2(double &x) {
    141     scanf("%lf", &x);
    142 }
    143 inline void read2(char *s) {
    144     scanf("%s", s);
    145 }
    146 inline void read2(char &c) {
    147     scanf(" %c", &c);
    148 }
    149 inline void readln2(char *s) {
    150     gets(s);
    151 }
    152 // fwrite->write
    153 struct Ostream_fwrite {
    154     char *buf, *p1, *pend;
    155     Ostream_fwrite() {
    156         buf = new char[BUF_SIZE];
    157         p1 = buf;
    158         pend = buf + BUF_SIZE;
    159     }
    160     void out(char ch) {
    161         if (p1 == pend) {
    162             fwrite(buf, 1, BUF_SIZE, stdout);
    163             p1 = buf;
    164         }
    165         *p1++ = ch;
    166     }
    167     void print(int x) {
    168         static char s[15], *s1;
    169         s1 = s;
    170         if (!x) *s1++ = '0';
    171         if (x < 0) out('-'), x = -x;
    172         while (x) *s1++ = x % 10 + '0', x /= 10;
    173         while (s1-- != s) out(*s1);
    174     }
    175     void println(int x) {
    176         static char s[15], *s1;
    177         s1 = s;
    178         if (!x) *s1++ = '0';
    179         if (x < 0) out('-'), x = -x;
    180         while (x) *s1++ = x % 10 + '0', x /= 10;
    181         while (s1-- != s) out(*s1);
    182         out('
    ');
    183     }
    184     void print(ll x) {
    185         static char s[25], *s1;
    186         s1 = s;
    187         if (!x) *s1++ = '0';
    188         if (x < 0) out('-'), x = -x;
    189         while (x) *s1++ = x % 10 + '0', x /= 10;
    190         while (s1-- != s) out(*s1);
    191     }
    192     void println(ll x) {
    193         static char s[25], *s1;
    194         s1 = s;
    195         if (!x) *s1++ = '0';
    196         if (x < 0) out('-'), x = -x;
    197         while (x) *s1++ = x % 10 + '0', x /= 10;
    198         while (s1-- != s) out(*s1);
    199         out('
    ');
    200     }
    201     void print(double x, int y) {
    202         static ll mul[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000LL, 100000000000LL, 1000000000000LL, 10000000000000LL, 100000000000000LL, 1000000000000000LL, 10000000000000000LL, 100000000000000000LL};
    203         if (x < -1e-12) out('-'), x = -x;
    204         x *= mul[y];
    205         ll x1 = (ll) floor(x);
    206         if (x - floor(x) >= 0.5) ++x1;
    207         ll x2 = x1 / mul[y], x3 = x1 - x2 * mul[y];
    208         print(x2);
    209         if (y > 0) {
    210             out('.');
    211             for (size_t i = 1; i < y && x3 * mul[i] < mul[y]; out('0'), ++i)
    212                 ;
    213             print(x3);
    214         }
    215     }
    216     void println(double x, int y) {
    217         print(x, y);
    218         out('
    ');
    219     }
    220     void print(char *s) {
    221         while (*s) out(*s++);
    222     }
    223     void println(char *s) {
    224         while (*s) out(*s++);
    225         out('
    ');
    226     }
    227     void flush() {
    228         if (p1 != buf) {
    229             fwrite(buf, 1, p1 - buf, stdout);
    230             p1 = buf;
    231         }
    232     }
    233     ~Ostream_fwrite() {
    234         flush();
    235     }
    236 } Ostream;
    237 inline void print(int x) {
    238     Ostream.print(x);
    239 }
    240 inline void println(int x) {
    241     Ostream.println(x);
    242 }
    243 inline void print(char x) {
    244     Ostream.out(x);
    245 }
    246 inline void println(char x) {
    247     Ostream.out(x);
    248     Ostream.out('
    ');
    249 }
    250 inline void print(ll x) {
    251     Ostream.print(x);
    252 }
    253 inline void println(ll x) {
    254     Ostream.println(x);
    255 }
    256 inline void print(double x, int y) {
    257     Ostream.print(x, y);
    258 }
    259 inline void println(double x, int y) {
    260     Ostream.println(x, y);
    261 }
    262 inline void print(char *s) {
    263     Ostream.print(s);
    264 }
    265 inline void println(char *s) {
    266     Ostream.println(s);
    267 }
    268 inline void println() {
    269     Ostream.out('
    ');
    270 }
    271 inline void flush() {
    272     Ostream.flush();
    273 }
    274 // puts->write
    275 char Out[OUT_SIZE], *o = Out;
    276 inline void print1(int x) {
    277     static char buf[15];
    278     char *p1 = buf;
    279     if (!x) *p1++ = '0';
    280     if (x < 0) *o++ = '-', x = -x;
    281     while (x) *p1++ = x % 10 + '0', x /= 10;
    282     while (p1-- != buf) *o++ = *p1;
    283 }
    284 inline void println1(int x) {
    285     print1(x);
    286     *o++ = '
    ';
    287 }
    288 inline void print1(ll x) {
    289     static char buf[25];
    290     char *p1 = buf;
    291     if (!x) *p1++ = '0';
    292     if (x < 0) *o++ = '-', x = -x;
    293     while (x) *p1++ = x % 10 + '0', x /= 10;
    294     while (p1-- != buf) *o++ = *p1;
    295 }
    296 inline void println1(ll x) {
    297     print1(x);
    298     *o++ = '
    ';
    299 }
    300 inline void print1(char c) {
    301     *o++ = c;
    302 }
    303 inline void println1(char c) {
    304     *o++ = c;
    305     *o++ = '
    ';
    306 }
    307 inline void print1(char *s) {
    308     while (*s) *o++ = *s++;
    309 }
    310 inline void println1(char *s) {
    311     print1(s);
    312     *o++ = '
    ';
    313 }
    314 inline void println1() {
    315     *o++ = '
    ';
    316 }
    317 inline void flush1() {
    318     if (o != Out) {
    319         if (*(o - 1) == '
    ') *--o = 0;
    320         puts(Out);
    321     }
    322 }
    323 struct puts_write {
    324     ~puts_write() {
    325         flush1();
    326     }
    327 } _puts;
    328 inline void print2(int x) {
    329     printf("%d", x);
    330 }
    331 inline void println2(int x) {
    332     printf("%d
    ", x);
    333 }
    334 inline void print2(char x) {
    335     printf("%c", x);
    336 }
    337 inline void println2(char x) {
    338     printf("%c
    ", x);
    339 }
    340 inline void print2(ll x) {
    341 #ifdef _WIN32
    342     printf("%I64d", x);
    343 #else
    344 #ifdef __linux
    345     printf("%lld", x);
    346 #else
    347     puts("error:can't recognize the system!");
    348 #endif
    349 #endif
    350 }
    351 inline void println2(ll x) {
    352     print2(x);
    353     printf("
    ");
    354 }
    355 inline void println2() {
    356     printf("
    ");
    357 }
    358 #undef ll
    359 #undef OUT_SIZE
    360 #undef BUF_SIZE
    361 };
    362 using namespace fastIO;
    363 typedef long long ll;
    364 int n,k;
    365 const int maxn=1e5+2;
    366 const int maxm=maxn*2;
    367 struct edge
    368 {
    369     int to;
    370     int nxt;
    371 }e[maxm];
    372 int head[maxn];
    373 int tot;
    374 int dp[maxn][2];
    375 
    376 void init()
    377 {
    378     memset(head,-1,sizeof(head));
    379     tot=0;
    380     memset(dp,0,sizeof(dp));
    381 }
    382 void addedge(int u,int v)
    383 {
    384     e[tot].to=v;
    385     e[tot].nxt=head[u];
    386     head[u]=tot++;
    387 }
    388 
    389 bool dfs(int u,int pa)
    390 {
    391     int flag=0;
    392     dp[u][0]=0;
    393     for(int i=head[u];i!=-1;i=e[i].nxt)
    394     {
    395         int v=e[i].to;
    396         if(v==pa) continue;
    397         if(dfs(v,u))
    398         {
    399             flag=1;
    400         }
    401         dp[u][0]+=dp[v][1];
    402     }
    403     if(flag)
    404     {
    405         dp[u][1]=dp[u][0]+1;
    406         return false;
    407     }
    408     else
    409     {
    410         dp[u][1]=dp[u][0];
    411         return true;
    412     }
    413 }
    414 int main()
    415 {
    416     int T;
    417     //scanf("%d",&T);
    418     read(T);
    419     //cout<<T<<endl;
    420     while(T--)
    421     {
    422         init();
    423         read(n);
    424         read(k);
    425         //cout<<n<<k<<endl;
    426         //scanf("%d%d",&n,&k);
    427         int x;
    428         for(int i=2;i<=n;i++)
    429         {
    430             read(x);
    431             //scanf("%d",&x);
    432             addedge(i,x);
    433             addedge(x,i);
    434         }
    435         dfs(1,-1);
    436         int cnt=dp[1][1];
    437         int tmp=cnt*2;
    438         int ans;
    439         if(k<=tmp)
    440         {
    441             ans=k/2;
    442             if(k%2) ans++;
    443         }
    444         else
    445         {
    446             ans=cnt+k-tmp;
    447         }
    448         printf("%d
    ",ans);
    449     }
    450     return 0;
    451 }
    树形dp

    树形dp的代码比赛是wa了,赛后才发现,原来是我dfs里开了全局变量flag,flag在其他层里被修改,改成局部变量就A了orz

  • 相关阅读:
    2-SAT
    模板 两次dfs
    SG函数与SG定理
    NIM博弈
    python 给小孩起名
    pytest 数据驱动
    pytest 结合selenium 运用案例
    字符串的转换方法与分割
    字符串的方法
    字符串常量池与字符串之间的比较
  • 原文地址:https://www.cnblogs.com/itcsl/p/7425199.html
Copyright © 2020-2023  润新知