心得:
状态极差,都怪放假,上一套的T3没改完,今天考试没有一点状态,开学恐惧症。(不恐惧作业或一调但还是很茫然)
T1能A掉实在是意外,杂题T1没做过,可能是人品守恒,(丢了钱今天才发现以后一定锁柜子QAQ),贪心不会证,凭感觉一点点瞎搞
T2和T3基本很颓很困,打了两个暴力都没调出来,恶心的题意,话说skyh口中很显然的dp式子很显然,但没有去想。
总之唯一想说的就是赶紧找到状态,即将进入高考奥赛双向战斗时期,紧张度和常规要提升
题解
T1我的做法真的很玄
输入(0,1)边权记为1,(1,1)记为3,(×,0)记为2
我们考虑一下 叶子节点和它父亲 ,如果将两个边权为1的一块处理,显然要比分别处理更优,而且要尽可能的去多处理,所以最后会剩至多一个待处理,
那这个怎么办?接着扔上去等着处理呗。
从1开始dfs,对于每个点,看它的每个儿子和相连两者的边,
分情况,这个边权k==1时,不管下面有没有剩,这个边仍要上去接着处理,(下面至多会剩一个,当然可以一块处理)
k==2的话可以接着往上考虑,
k==3想一个贪心,如果让这个边翻过来再反回去,不会比 直接处理剩的 更优,所以k==3时,直接把有剩的直接贡献到ans里就好
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<queue> 6 #include<vector> 7 #define R register 8 using namespace std; 9 inline int read() 10 { 11 int f=1,x=0;char ch=getchar(); 12 while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} 14 return f*x; 15 } 16 const int maxn=1000005; 17 struct node{ 18 int v,nxt,da; 19 }e[2*maxn];int h[maxn],nu; 20 void add(int x,int y,int fl) 21 { 22 e[++nu].v=y; 23 e[nu].da=fl; 24 e[nu].nxt=h[x]; 25 h[x]=nu; 26 } 27 int n,f[maxn],ans; 28 int dfs(int x,int xf) 29 { 30 int cnt=0; 31 for(int i=h[x];i;i=e[i].nxt) 32 { 33 int y=e[i].v,k=e[i].da; 34 if(y==xf)continue; 35 int nw=dfs(y,x); 36 //cout<<x<<" "<<y<<" "<<k<<endl; 37 if(k==1){cnt++;continue;} 38 if(!nw)continue; 39 if(k==3)ans++; 40 else cnt++; 41 } 42 ans+=cnt/2; 43 if(cnt%2==0)return 0; 44 return 1; 45 } 46 int main() 47 { 48 //freopen("data","r",stdin); 49 n=read(); 50 int qj1=1,num1=0; 51 for(int x=2;x<=n;++x) 52 { 53 int y=read(),s=read(),t=read(),fl; 54 if(y!=1)qj1=0; 55 if(t==0)fl=2; 56 if(s==0&&t==1)num1++,fl=1; 57 if(s==1&&t==1)fl=3; 58 add(x,y,fl); 59 add(y,x,fl); 60 } 61 if(qj1){printf("%d\n",(num1+1)/2);return 0;} 62 int nw=dfs(1,0); 63 ans+=nw; 64 printf("%d\n",ans); 65 }/* 66 g++ 1.cpp -o 1 67 ./1 68 69 */