zoukankan      html  css  js  c++  java
  • 「模拟8.21」虎

    正解贪心考场只骗到了70分

    做法一:

    现将没有限制的边缩掉然后连边,

    这样我们直接采用贪心的做法,因为每个边最多只会被反一次,

    那么从叶子节点向上对于一个需要修改的边没直接令他向上直到不能修改

    注意处理连在lca上有两条链的现象

     1 #include<bits/stdc++.h>
     2 #define MAXN 2100000
     3 using namespace std;
     4 struct node{int to;int n;}e[MAXN];
     5 int tot,head[MAXN];
     6 int n;bool ok_1;int work_1;
     7 int fa[MAXN];int col[MAXN];
     8 bool h[MAXN];
     9 vector<int>son[MAXN];
    10 void add(int u,int v)
    11 {
    12      e[++tot].to=v;e[tot].n=head[u];head[u]=tot;
    13 }
    14 void work1()
    15 {
    16      if(work_1%2==0)printf("%d
    ",work_1/2);
    17      else printf("%d
    ",work_1/2+1);
    18 }
    19 int ans=0;
    20 int biao[MAXN];
    21 void updata(int x)
    22 {
    23      int me=x;
    24      while(col[me]==0&&me!=1)
    25      {
    26            col[me]^=1;
    27            me=fa[me];
    28      }        
    29      biao[me]^=1;
    30      if(biao[me]==1)
    31      {
    32         ans++;        
    33      }
    34      return ;
    35 }
    36 void DFS(int x)
    37 {
    38      for(int i=head[x];i;i=e[i].n)
    39      {
    40          int to=e[i].to;
    41          DFS(to);
    42          if(col[to]==0)
    43          {
    44             updata(to);
    45          }
    46      }
    47      return ;
    48 }
    49 signed main()
    50 {
    51      scanf("%d",&n);ok_1=1;
    52      for(int i=2;i<=n;++i)
    53      {
    54          int x,y,z;
    55          scanf("%d%d%d",&x,&y,&z);
    56          if(x!=1)ok_1=0;
    57          if(z==1&&y==0)work_1++;
    58          if(z==0)h[i]=1;
    59          fa[i]=x;col[i]=y;
    60          son[x].push_back(i);
    61      }
    62      for(int i=2;i<=n;++i)
    63      {
    64          int me=i;
    65          if(h[i]==1)
    66          {
    67              while(h[me]==1&&me!=1)
    68                    me=fa[me];
    69              for(int j=0;j<son[i].size();++j)
    70              {
    71                  fa[son[i][j]]=me;
    72              }
    73          }
    74      }
    75      for(int i=2;i<=n;++i)
    76      {
    77          if(h[i])continue;
    78          add(fa[i],i);
    79      }
    80      if(ok_1)
    81      {
    82         work1();
    83         return 0;
    84      }
    85      DFS(1);
    86      printf("%d
    ",ans);
    87 }
    View Code

    做法二

    我们如果能在一个lca上连两条边,那么这一定是优的

    那么我们从下向上统计奇数偶数边的情况

    参考cyf的代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #define INF 0x7fffffff
     4 using namespace std;
     5 const int MAXN=1000010;
     6 inline int minn(int a,int b){return a<b?a:b; }
     7 inline int read(){
     8     int s=0,w=0;char ch=getchar();
     9     while(ch<'0'||ch>'9')w|=(ch=='-'),ch=getchar();
    10     while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    11     return w?-s:s;
    12 }
    13 #define kd (read())
    14 int n;
    15 struct rr{
    16     int nt,w,to;
    17 }bl[MAXN<<1];int hd[MAXN],itot;
    18 void add(int x,int y,int z){
    19     if(x==y)return ;
    20     bl[++itot].to=y;
    21     bl[itot].nt=hd[x];
    22     bl[itot].w=z;
    23     hd[x]=itot;
    24 }
    25 int fat[MAXN];
    26 inline int find(int x){
    27     if(!fat[x]||fat[x]==x)return x;
    28     return fat[x]=find(fat[x]);
    29 }
    30 struct node{
    31     int fr,to,y;
    32 }Q[MAXN];int qtot;
    33 int ans=0;
    34 void dfs(int u,int fa,int id){//id of edge fa->u  
    35     int cnt=0;
    36     for(int i=hd[u];i;i=bl[i].nt)
    37         if(bl[i].to!=fa){
    38             dfs(bl[i].to,u,i);
    39             cnt+=(bl[i].w==0);
    40         }
    41     if(cnt&1){
    42         ans+=cnt/2;
    43         if(bl[id].w==1)++ans;
    44     }
    45     else ans+=cnt/2;
    46 }
    47 int main(){
    48     //freopen("da.in","r",stdin);
    49     n=kd;
    50     bool pd_30=1;
    51     int cnt=0;
    52     for(int i=2,x,y,z;i<=n;++i){
    53         x=kd;y=kd;z=kd;
    54         pd_30&=(x==1);
    55         if(z&&!y)++cnt;
    56         if(!z)fat[find(i)]=find(x);
    57         Q[++qtot].fr=i,Q[qtot].to=x,Q[qtot].y=y;
    58     }
    59     if(pd_30){
    60         if(cnt&1)printf("%d
    ",cnt/2+1);
    61         else printf("%d
    ",cnt/2);
    62         return 0;
    63     }
    64     else{
    65         for(int i=1;i<=qtot;++i){
    66             add(find(Q[i].fr),find(Q[i].to),Q[i].y);
    67             add(find(Q[i].to),find(Q[i].fr),Q[i].y);
    68         }
    69         bl[0].w=1;
    70         dfs(find(1),0,0);
    71         printf("%d
    ",ans);
    72         return 0;
    73     }
    74 }
    View Code
  • 相关阅读:
    Oracle sql的基本优化写法和思路。
    Linux的简单介绍和开发基本运维时候用到的命令
    Nginx的使用(反向代理,负载均衡)
    Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)
    Mybatis Blob和String互转,实现文件上传等。
    Ckeditor上传图片返回的JS直接显示出来,未执行!!!
    学习中的错误——ubuntu 14.04 LTS 启动eclipse报错
    2016计算机大会后记——机器学习:发展与未来
    2016计算机大会后记——大数据时代的模式识别
    近期编程问题——epoll failed:bad file descriptor
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11420940.html
Copyright © 2011-2022 走看看