zoukankan      html  css  js  c++  java
  • CF#190DIV.1

    
    
     1 /*
     2 CF#190DIV.1-C
     3 题意:给你n个结点的树,给这些结点标记字母AB..Z,对于标记相同的结点路径上
     4 的结点的标记必须有一个是大于该标记的;问是否可以标记(A是最大标记)
     5 
     6 分析:整天思路就是找一个点,然后标记为最大标记i,然后再分别以最大标记i+1,标记该点的子树
     7 依次递归;最终如果标记<=Z就是可以的;
     8 因为只有10^5个点,最长情况下需要logn个不同的标记对于n个结点的树(成一条链)
     9 2^26>log(10^5) 所以必定有解;
    10 
    11 而那个点,最优的应该就是树的重心,重心的定义:去掉这个点后,树给分成a个连通分量,每个连通分量
    12 仍然是一棵树,并且a个连通分量中最大结点数最小;
    13 
    14 求法:这棵树的结点树为all,dfs()下去,同时记录该结点每棵子树的结点个数,那么该结点的
    15 父亲结点那棵子树的结点树就是all-sum_soncnt-1;
    16 用di[i]表示结点i的子树中结点个数最大的数,那么di[]最小的那个点就是重心
    17 
    18 */
    19 #include<cstdio>
    20 #include<cstring>
    21 #include<iostream>
    22 #include<cmath>
    23 #include<algorithm>
    24 #include<cstdlib>
    25 #include<vector>
    26 using namespace std;
    27 const int N=100000+10;
    28 vector<int> edge[N];
    29 int n;
    30 int how[N];
    31 int di[N];
    32 void read(){
    33     memset(how,-1,sizeof(how));
    34     for (int i=0;i<=n;i++) edge[i].clear();
    35     for (int i=0;i<n-1;i++){
    36         int u,v;scanf("%d%d",&u,&v);
    37         edge[u].push_back(v);
    38         edge[v].push_back(u);
    39     }
    40 }
    41 
    42 int son_cnt[N];
    43 void find_center(int rt,int fa,int &id,int all){
    44     int sum=1,tmp=0;
    45     for (int i=0;i<edge[rt].size();i++){
    46         int c=edge[rt][i];
    47         if (how[c]!=-1 || c==fa) continue;
    48         find_center(c,rt,id,all);
    49         sum+=son_cnt[c];
    50         tmp=max(tmp,son_cnt[c]);
    51     }
    52     di[rt]=max(tmp,all-sum);
    53     if (id==-1 || di[id]>di[rt]) id=rt;
    54     son_cnt[rt]=sum;
    55 }
    56 void findall(int rt,int fa,int &all){
    57     all++;
    58     for (int i=0;i<edge[rt].size();i++){
    59         int c=edge[rt][i];
    60         if (how[c]!=-1 || c==fa)continue;
    61         findall(c,rt,all);
    62     }
    63 }
    64 void work(int rt,int tar){
    65     int all=0;
    66     findall(rt,-1,all);
    67 
    68     int id=-1;
    69     find_center(rt,-1,id,all);
    70 
    71     how[id]=tar;
    72     for (int i=0;i<edge[id].size();i++){
    73         int c=edge[id][i];
    74         if (how[c]!=-1) continue;
    75         work(c,tar+1);
    76     }
    77 
    78 }
    79 int main(){
    80     while (~scanf("%d",&n)){
    81         read();
    82         work(1,0);
    83         for (int i=1;i<n;i++){
    84             printf("%c ",how[i]+'A');
    85         }printf("%c
    ",how[n]+'A');
    86     }
    87     return 0;
    88 }
    
    
    
     
     1 /*
     2 CF#190DIV.1-B
     3 题意:看过游戏王的人的知道,现在轮到你攻击了,问你能给对方照成的最大伤害是多少
     4 一次有效的攻击必须是己方的怪兽的攻击力大于等于对方的攻击了;
     5 对方怪兽成防御状况攻击没有伤害,成攻击状况伤害为己方攻击减去对方攻击力
     6 
     7 分析:题解里有很多种方法,贪心,dp,最小费用最大流
     8 下面是贪心:分两类,一类是能达到直接攻击的方案,一类是不能达到直接攻击的方案
     9 
    10 写代码遇到的问题:
    11         下面代码中标记为$的那一行代码,位置放到了下面标记@的位置,导致当n3==0时,并且
    12         前一组数据使v2[0]>v3[0],导致样例跑挂,这个错误很难找出来,如果没有数据的话,
    13         所以如果清空的代价很小,那么能清空的就清空,该早点判断就早点判断
    14 
    15 */
    16 #include<cstdio>
    17 #include<cstring>
    18 #include<iostream>
    19 #include<cstdlib>
    20 #include<algorithm>
    21 #include<cmath>
    22 #include<vector>
    23 using namespace std;
    24 typedef long long LL;
    25 const int N=100+10;
    26 int n,m;
    27 int f[N],v1[N],v2[N];
    28 int ans;
    29 int work(){
    30     int flag1=0;
    31     int v3[N],v4[N],n3=0,n4=0;
    32     for (int i=0;i<n;i++){
    33         if (f[i]==1) v3[n3++]=v1[i];
    34         else v4[n4++]=v1[i];
    35     }
    36     sort(v3,v3+n3); sort(v4,v4+n4);
    37     int vis[N];
    38     memset(vis,0,sizeof(vis));
    39     sort(v2,v2+m);
    40     int j=0;
    41     for (int i=0;i<m;i++){
    42         if (j==n3) break;//$
    43         if (v2[i]>v3[j]){
    44             vis[i]=1;
    45             j++;
    46         }
    47         /*if (j==n3) break;@*/
    48     }
    49     if (j!=n3) flag1=1;
    50     j=0;
    51     for (int i=0;i<m;i++){
    52         if (j==n4) break;
    53         if (vis[i]==0){
    54             if (v2[i]>=v4[j]){
    55                 j++;
    56             }
    57 
    58         }
    59     }
    60     if (j!=n4) flag1=1;
    61 
    62     int sum1=0,sum2=0;
    63     for (int i=0;i<m;i++) if (vis[i]==0) sum1+=v2[i];
    64     for (int i=0;i<n4;i++) sum2+=v4[i];
    65     if (flag1==0)ans=max(ans,sum1-sum2);
    66 
    67     j=m-1;
    68     int tmp=0;
    69     for (int i=0;i<n4;i++){
    70         if (v2[j]>=v4[i]) {
    71             tmp+=v2[j]-v4[i];
    72             j--;
    73         }
    74     }
    75     ans=max(ans,tmp);
    76     cout<<ans<<endl;
    77 
    78 }
    79 int main(){
    80 //  cout<<4%0<<endl;
    81     while (cin>>n>>m){
    82         char s[10];
    83         ans=0;
    84         for (int i=0;i<n;i++){
    85             scanf("%s%d",s,v1+i);
    86             if(s[0]=='A') f[i]=0;
    87             else f[i]=1;
    88         }
    89         for (int i=0;i<m;i++) scanf("%d",v2+i);
    90         work();
    91     }
    92 
    93     return 0;
    94 }
     1 /*
     2 CF#190DIV.1-A
     3 题意:一个机器人站在原地(0,0)给你一串只包含UDLR的字符串,机器人只能按照这个串的顺序
     4 来前进,并且可以无限次重复,问时候可以到达(a,b);
     5 
     6 分析:有一些trick,比如循环的次数只能是正数,不能除零
     7 还是刚开始就分类分清楚的好,不然代码中的一些逻辑真得搞不清楚
     8 
     9 */
    10 #include<cstdio>
    11 #include<cstring>
    12 #include<cstdlib>
    13 #include<iostream>
    14 #include<cmath>
    15 #include<cstdio>
    16 #include<algorithm>
    17 using namespace std;
    18 typedef long long LL;
    19 const int N=100+10;
    20 char s[N];
    21 const int nx[4]={0,0,-1,1};
    22 const int ny[4]={1,-1,0,0};
    23 LL a,b;
    24 LL X,Y;
    25 void init(){
    26     X=Y=0;
    27     for (int i=0;s[i];i++){
    28         int j;
    29         if (s[i]=='U') j=0;
    30         else if (s[i]=='D') j=1;
    31         else if (s[i]=='L') j=2;
    32         else if (s[i]=='R') j=3;
    33         X+=nx[j]; Y+=ny[j];
    34     }
    35 }
    36 void work(){
    37     int tx=0,ty=0;
    38     int flag=0;
    39     for (int i=0;s[i];i++){
    40         if (X==0 && Y==0){
    41             if (a==tx && b==ty) flag=1;
    42         }else if (X==0 && Y!=0){
    43             if (a==tx && (b-ty)%Y==0 && (b-ty)/Y>=0) flag=1;
    44         }else if (X!=0 && Y==0){
    45             if (b==ty && (a-tx)%X==0 && (a-tx)/X>=0) flag=1;
    46         }else if (X!=0 && Y!=0){
    47             if ((a-tx)%X==0 && (b-ty)%Y==0 && (a-tx)/X==(b-ty)/Y && (a-tx)/X>=0) flag=1;
    48         }
    49         if (flag) break;
    50         int j;
    51         if (s[i]=='U') j=0;
    52         else if (s[i]=='D') j=1;
    53         else if (s[i]=='L') j=2;
    54         else if (s[i]=='R') j=3;
    55         tx+=nx[j]; ty+=ny[j];
    56     }
    57     puts(flag?"Yes":"No");
    58 }
    59 int main(){
    60     while (cin>>a>>b){
    61         scanf("%s",s);
    62         init();
    63         work();
    64     }
    65 
    66     return 0;
    67 }
  • 相关阅读:
    Mysq数据库备份(win)
    Mysql保存中文乱码问题
    MySql常用操作
    win下 mysql远程连接设置
    windows下redis的使用
    栈和队列
    ffmpeg 常用命令
    nginx https配置模板
    openssl 、nginx生成配置自签名证书
    https、公钥,私钥,数字证书
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3162407.html
Copyright © 2011-2022 走看看