码迷,mamicode.com
首页 > 其他好文 > 详细

【CF1244D】Paint the Tree(树形DP)

时间:2019-10-13 23:33:47      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:sig   tree   div   info   技术   struct   思路   def   namespace   

题意:

技术图片

 

n<=1e5,1<=a[i][j]<=1e9

思路:

技术图片

 

 不是很懂INF为什么要开到1e15,我觉得只要1e14就好

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 //typedef pair<ll,ll>P;
 11 #define N  200010
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 struct node
 28 {
 29     int x,y;
 30 }pre[N][3][3];
 31 
 32 ll dp[N][3][3];
 33 ll a[N][3];
 34 int head[N],vet[N],nxt[N],d[N],c[N],son[N],f[N],tot,n;
 35 
 36 int read()
 37 {
 38    int v=0,f=1;
 39    char c=getchar();
 40    while(c<48||57<c) {if(c==-) f=-1; c=getchar();}
 41    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 42    return v*f;
 43 }
 44 
 45 void add(int a,int b)
 46 {
 47     nxt[++tot]=head[a];
 48     vet[tot]=b;
 49     head[a]=tot;
 50 }
 51 
 52 void dfs(int u,int fa)
 53 {
 54     //printf("dfs u=%d fa=%d\n",u,fa);
 55     int e=head[u],s=0;
 56     rep(i,0,2)
 57      rep(j,0,2) dp[u][i][j]=1e15;
 58     while(e)
 59     {
 60         int v=vet[e];
 61         if(v!=fa)
 62         {
 63             s++;
 64             son[u]=v;
 65             f[v]=u;
 66             dfs(v,u);
 67         }
 68         e=nxt[e];
 69     }
 70     if(u==1&&d[1]==2)
 71     {
 72         //printf("case 2\n");
 73         return;
 74     }
 75 
 76     if(s==0)
 77     {
 78         rep(i,0,2)
 79          rep(j,0,2)
 80           if(i!=j) dp[u][i][j]=a[u][i];
 81     }
 82      else
 83      {
 84          int v=son[u];
 85          //printf("u=%d v=%d\n",u,v);
 86          rep(i,0,2)
 87           rep(j,0,2)
 88            rep(k,0,2)
 89             if(i!=j&&j!=k&&i!=k)
 90             {
 91                 if(dp[u][i][j]>dp[v][j][k]+a[u][i])
 92                 {
 93                     dp[u][i][j]=dp[v][j][k]+a[u][i];
 94                     pre[u][i][j].x=j;
 95                     pre[u][i][j].y=k;
 96                 }
 97             }
 98 
 99      }
100 
101 
102 }
103 
104 void print()
105 {
106     /*rep(i,1,n)
107      rep(j,0,2)
108       rep(k,0,2)
109        if(j!=k) printf("i=%d j=%d k=%d dp[i][j][k]=%I64d\n",i,j,k,dp[i][j][k]);*/
110     if(d[1]==1)
111     {
112         ll ans=1e15;
113         int x=0,y=0;
114         rep(i,0,2)
115          rep(j,0,2)
116           if(i!=j&&dp[1][i][j]<ans)
117           {
118                 ans=dp[1][i][j];
119                 x=i; y=j;
120           }
121         int u=1;
122         while(u)
123         {
124             c[u]=x;
125             int x1=pre[u][x][y].x;
126             int y1=pre[u][x][y].y;
127             u=son[u];
128             x=x1,y=y1;
129         }
130         printf("%I64d\n",ans);
131         rep(i,1,n) printf("%d ",c[i]+1);
132     }
133      else
134      {
135          int k1=0,k2=0;
136          rep(i,1,n)
137           if(f[i]==1){k1=i; break;}
138          per(i,n,1)
139           if(f[i]==1){k2=i; break;}
140          int x1,y1,x2,y2,z;
141          ll ans=1e15;
142          rep(i,0,2)
143           rep(j,0,2)
144            rep(k,0,2)
145             rep(p,0,2)
146              rep(q,0,2)
147               if(i!=j&&i!=k&&j!=k&&j!=p&&p!=i&&i!=q&&k!=q&&dp[k1][j][p]+dp[k2][k][q]+a[1][i]<ans)
148               {
149                   ans=dp[k1][j][p]+dp[k2][k][q]+a[1][i];
150                   z=i;
151                   x1=j; y1=p;
152                   x2=k; y2=q;
153               }
154          c[1]=z;
155          int u=k1,x=x1,y=y1;
156          while(u)
157          {
158              c[u]=x;
159              int x1=pre[u][x][y].x;
160              int y1=pre[u][x][y].y;
161              u=son[u];
162              x=x1,y=y1;
163          }
164          u=k2,x=x2,y=y2;
165          while(u)
166          {
167              c[u]=x;
168              int x1=pre[u][x][y].x;
169              int y1=pre[u][x][y].y;
170              u=son[u];
171              x=x1,y=y1;
172          }
173          printf("%I64d\n",ans);
174          rep(i,1,n) printf("%d ",c[i]+1);
175      }
176 
177 }
178 
179 int main()
180 {
181     //freopen("1.in","r",stdin);
182     n=read();
183     rep(j,0,2)
184      rep(i,1,n) scanf("%I64d",&a[i][j]);
185     rep(i,1,n) head[i]=d[i]=0;
186     tot=0;
187     rep(i,1,n-1)
188     {
189         int x=read(),y=read();
190         add(x,y);
191         add(y,x);
192         d[x]++; d[y]++;
193     }
194     int flag=1;
195     rep(i,1,n)
196      if(d[i]>=3) flag=0;
197     if(!flag)
198     {
199         printf("-1\n");
200         return 0;
201     }
202     dfs(1,0);
203     print();
204     return 0;
205 }

 

【CF1244D】Paint the Tree(树形DP)

标签:sig   tree   div   info   技术   struct   思路   def   namespace   

原文地址:https://www.cnblogs.com/myx12345/p/11668902.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!