CF1296F Berland Beauty

构造题

题意:一颗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;
} 
View Code
#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;
} 
View Code

猜你喜欢

转载自www.cnblogs.com/Urchin-C/p/12288503.html