【CF1244D】Paint the Tree(树形DP,树)

题意:

 

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 }

 实际上只有1条或者2条从1下来的链,枚举1和与1相邻的颜色然后就能推出整条链

  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 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-6;
 29       ll INF=1e15;
 30       int da[4]={-1,1,0,0};
 31       int db[4]={0,0,-1,1};
 32 
 33 struct node
 34 {
 35     int x,y;
 36 }pre[N][3][3];
 37 
 38 ll a[N][3];
 39 int head[N],vet[N],nxt[N],f[N],g[N],b[N],c[N],d[N],p[N],tot,son;
 40 
 41 int read()
 42 {
 43    int v=0,f=1;
 44    char c=getchar();
 45    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 46    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 47    return v*f;
 48 }
 49 
 50 void add(int a,int b)
 51 {
 52     nxt[++tot]=head[a];
 53     vet[tot]=b;
 54     head[a]=tot;
 55 }
 56 
 57 void dfs(int u,int fa)
 58 {
 59     int e=head[u];
 60     while(e)
 61     {
 62         int v=vet[e];
 63         if(v!=fa)
 64         {
 65             f[v]=u;
 66             g[u]=v;
 67             if(u==1)
 68             {
 69                 son++;
 70                 p[son]=v;
 71             }
 72             dfs(v,u);
 73         }
 74         e=nxt[e];
 75     }
 76 }
 77 
 78 int main()
 79 {
 80     //freopen("1.in","r",stdin);
 81     int n=read();
 82     rep(j,0,2)
 83      rep(i,1,n) scanf("%I64d",&a[i][j]);
 84     rep(i,1,n) head[i]=d[i]=0;
 85     tot=0;
 86     rep(i,1,n-1)
 87     {
 88         int x=read(),y=read();
 89         add(x,y);
 90         add(y,x);
 91         d[x]++; d[y]++;
 92     }
 93     int flag=1;
 94     rep(i,1,n)
 95      if(d[i]>=3) flag=0;
 96     if(!flag)
 97     {
 98         printf("-1\n");
 99         return 0;
100     }
101     son=0;
102     dfs(1,0);
103     ll ans=INF;
104     if(son==1)
105     {
106         rep(x,0,2)
107         {
108             int u=p[1];
109             rep(y,0,2)
110              if(x!=y)
111              {
112                 b[1]=x; b[u]=y;
113                 int k=u;
114                 while(k)
115                 {
116                     k=g[k];
117                     if(!k) break;
118                     b[k]=3-b[f[k]]-b[f[f[k]]];
119                 }
120                  ll s=0;
121                  rep(i,1,n) s+=a[i][b[i]];
122                  if(s<ans)
123                  {
124                     ans=s;
125                     rep(i,1,n) c[i]=b[i];
126                  }
127              }
128         }
129     }
130      else
131      {
132          int u1=p[1],u2=p[2];
133          rep(x,0,2)
134          rep(y,0,2)
135           rep(z,0,2)
136            if(x!=y&&x!=z&&y!=z)
137            {
138                 b[1]=x; b[u1]=y;
139                 int k=u1;
140                 while(k)
141                 {
142                     k=g[k];
143                     if(!k) break;
144                     b[k]=3-b[f[k]]-b[f[f[k]]];
145                 }
146                 b[u2]=z;
147                 k=u2;
148                 while(k)
149                 {
150                     k=g[k];
151                     if(!k) break;
152                     b[k]=3-b[f[k]]-b[f[f[k]]];
153                 }
154                 ll s=0;
155                 rep(i,1,n) s+=a[i][b[i]];
156                 if(s<ans)
157                 {
158                     ans=s;
159                     rep(i,1,n) c[i]=b[i];
160                 }
161            }
162      }
163 
164     printf("%I64d\n",ans);
165     rep(i,1,n) printf("%d ",c[i]+1);
166     return 0;
167 }

 

posted on 2019-10-13 22:52  myx12345  阅读(128)  评论(0编辑  收藏  举报

导航