标签:pre span color iostream bre scan hid max nss
题意:
有一颗树,n个点,让你涂色,有三种颜色,每个节点每涂一种颜色都有一种成本。要求,所有连续的三个点都要有不同的颜色,并且总成本要最小。
无法满足就输出-1,否则输出成本和方案。
思路:
显然,如果有一个点的度>=3,那么肯定不满足,所以一定得是一条链。
如果头两个的颜色确定了,那么接下来的n-2个点的颜色也就确定了,
所以其实只有6种情况,模拟一下就好了。
代码:
#include <stdio.h> #include <string.h> #include <cmath> #include <iostream> #include <vector> using namespace std; typedef long long int ll; const double pi = acos(-1); const int maxn = 1e5 + 10; ll c[maxn][3],id[maxn]; int n,vis[maxn],mp[maxn][2],anss[maxn],tempp[maxn]; void add(int u,int v) { if(vis[u] == 0) mp[u][0] = v; else mp[u][1] = v; vis[u]++; } int main() { while(scanf("%d",&n) != EOF){ for(int i = 0;i < 3;i++) for(int j = 1;j <= n;j++) scanf("%lld",&c[j][i]); int u,v; memset(vis,0,sizeof(vis)); for(int i = 0;i < n - 1;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } int st; for(int i = 1;i <= n;i++){ if(vis[i] >= 3){ printf("-1\n"); return 0; } if(vis[i] == 1) st = i; } int cnt = 0; id[0] = -1; id[++cnt] = st; while(cnt < n){ u = mp[id[cnt]][0]; v = mp[id[cnt]][1]; if(u == id[cnt - 1]) id[++cnt] = v; else id[++cnt] = u; } ll ans = 1e18; int p; for(int i = 0;i < 3;i++){ for(int j = 0;j < 3;j++){ if(i == j) continue; tempp[1] = i; tempp[2] = j; ll temp = c[id[1]][tempp[1]] + c[id[2]][tempp[2]]; for(int k = 3;k <= n;k++){ for(int h = 0;h < 3;h++){ if(h != tempp[k - 1] && h != tempp[k - 2]){ p = h; break; } } temp += c[id[k]][p]; tempp[k] = p; } if(ans > temp){ ans = temp; for(int k = 1;k <= n;k++) anss[id[k]] = tempp[k]; } } } printf("%lld\n",ans); for(int i = 1;i <= n;i++) printf("%d ",anss[i] + 1); puts(""); } return 0; }
标签:pre span color iostream bre scan hid max nss
原文地址:https://www.cnblogs.com/InitRain/p/12409127.html