构造题
题意:一颗n个结点的树,需要满足m个条件,即u到v的最短路径经过的边权最小是w。
暴力O(n2)一种,lca(mlog2n)一种,cf总样例的时间:47.41s 6.09s
暴力预处理出以u为根节点的v的父节点,fa[u][v],
对路径染色的时候将条件要么从小到大排序,要么尽量取大值
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 1e9 + 7; const int maxn = 5e3 + 10; const int INF = 0x3f3f3f3f; struct node { int v, nxt; }edge[2 * maxn]; int tot, head[maxn]; void add(int u, int v) { edge[++tot].v = v; edge[tot].nxt = head[u]; head[u] = tot; } int uu[maxn], vv[maxn]; int f[maxn][maxn]; int w[maxn][maxn]; int a[maxn],b[maxn],ww[maxn]; int n; void init() { For(i,0,n+1)f[i][i]=i; For(i,0,n+1) For(j,0,n+1) w[i][j] = -INF; } int root,m; void dfs(int u, int fa) { f[root][u] = fa; for (int i = head[u]; i; i = edge[i].nxt) { int v = edge[i].v; if (v == fa) continue; dfs(v, u); } } void color() { For(i,0,m) { int u = read(), v = read(), minw = read(); a[i] = u; b[i] = v; ww[i] = minw; int fv = v; do { v = fv; fv = f[u][v]; Max(w[fv][v], minw); w[v][fv] = w[fv][v]; } while (fv != u); } } bool check() { For(i,0,m){ int u = a[i], v = b[i], minw = ww[i]; int fv = v; bool flag = false; do { v = fv; fv = f[u][v]; if (w[fv][v] < minw) return false; else if (w[fv][v] == minw) flag = true; } while (fv != u); if (flag == false) return false; } return true; } int main () { n = read(); For(i,1,n) { int u,v; scdd(u,v); uu[i]=u; vv[i]=v; add(u,v);add(v,u); } init(); For(i,0,n+1){ root = i; dfs(i,i); } m = read(); color(); if (check()) { For(i,1,n){ printf("%d ", max(1,w[uu[i]][vv[i]])); }puts(""); } else puts("-1"); return 0; }
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> using namespace std; #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define prl(a) printf("%lld\n",a) #define prd(a) printf("%d\n",a) #define prf(a) printf("%lf\n",a) #define ptd(a) printf("%d ",a) #define scf(a) scanf("%lf",&a) #define scff(a,b) scanf("%lf%lf",&a,&b) #define scfff(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define rint register int #define mem(a) memset(a,0,sizeof(a)) #define rush() int T;scd(T);while(T--) #define lc(i) (i<<1) #define rc(i) (i<<1|1) #define mp make_pair #define lowbit(x) (x&(-x)) #define For(i,st,en) for(int i=st;i<en;++i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(), (x).end() template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; } template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; } typedef long long ll; typedef double db; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;} const ll mod = 1e9 + 7; const int maxn = 5e3 + 10; const int maxf = 1e6; const int INF = 0x3f3f3f3f; int n, m; struct node { int v, nxt; int id; } edge[2 * maxn]; int tot = 1,head[maxn]; void add(int u, int v, int id) { edge[++tot].v = v; edge[tot].id = id; edge[tot].nxt = head[u]; head[u] = tot; } struct qnode{ int u,v,w; bool operator<(const qnode& a){ return this->w < a.w; } }q[maxn]; int lg[maxn]; int ew[maxn]; int fa[maxn][15],h[maxn],eid[maxn]; void init(){ lg[1]=0; For(i,2,maxn){ lg[i]=lg[i>>1]+1; } } void dfs(int u, int f){ h[u]=h[f]+1; fa[u][0]=f; for (int i = 1; (1<<i) <= h[u]; ++i) fa[u][i] = fa[fa[u][i-1]][i-1]; for (int i = head[u]; i; i = edge[i].nxt){ if (edge[i].v == f) continue; dfs(edge[i].v, u); eid[edge[i].v] = edge[i].id; } } int lca(int u, int v){ if (h[u] < h[v]) swap(u,v); while(h[u] > h[v]) u = fa[u][lg[h[u]-h[v]]]; if (u==v) return u; for (int i = lg[h[u]]; ~i; --i) if(fa[u][i]!=fa[v][i]) { u = fa[u][i]; v = fa[v][i]; } return fa[u][0]; } int main () { n = read(); init(); For(i,1,n){ int u = read(), v = read(); add(u,v,i); add(v,u,i); ew[i] = maxf; } dfs(1, 0); m = read(); for (int i = 0; i < m; ++i) { q[i].u = read(); q[i].v = read(); q[i].w = read(); } sort(q, q + m); For(i,0,m){ int u = q[i].u, v = q[i].v, w = q[i].w; int LCA = lca(u, v); while (u != LCA) { ew[eid[u]] = w; u = fa[u][0]; } while (v != LCA) { ew[eid[v]] = w; v = fa[v][0]; } } For(i,0,m){ int u = q[i].u, v = q[i].v, w = q[i].w; int LCA = lca(u, v), mi = maxf; while (u != LCA) { Min(mi, ew[eid[u]]); u = fa[u][0]; } while (v != LCA) { Min(mi, ew[eid[v]]); v = fa[v][0]; } if(mi != w){ puts("-1"); return 0; } } For(i,1,n) printf("%d ", ew[i]); return 0; }