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 }