染色(普通题)

染色

N 个点M 条边的有向无环图,无重边和自环。一开始所有的点都是颜色0。接下来有Q 次操作,每次操作形如x d c 表示将与点x 距离不超过d 的点全部染成颜色c(同一个点之后染的颜色会覆盖之前的)。问Q 次操作结束后每个点的颜色。100% 的数据N;M;Q <=100000; 0 <=d《=10; 1<=c<=100000

如果是有向图的话,无脑暴力直接就过了(注意要用链式前向星,会快一点)
因为标准程序所以大家都有0
无向图
就是要做一点优化,倒着做上来,因为最后一次染色是最终染色所以只要做最后一次就可以

上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

#define X first
#define Y second
#define N 100010
#define M 11

typedef long long ll;
const int INF=1<<30;

int n,m;
int f[N][M],cnt,head[N];

struct NODE
{
    int v,d,c;
}Q[N];
struct Edge{
    int next,to;
}e[1000005];
void add(int u,int v){
    cnt++;
    e[cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void Solve(int v,int d,int c)
{
    if (f[v][d]) return;
    f[v][d]=c;
    if (d==0) return;
    for (int i=head[v];i;i=e[i].next) 
      Solve(e[i].to,d-1,c);
    Solve(v,d-1,c);
}

int main()
{
    //freopen("color.in","r",stdin);
    //freopen("color.out","w",stdout);

    int q;
    scanf("%d%d%d",&n,&m, &q);
    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }   
    for (int i=1;i<=q;i++) scanf("%d%d%d",&Q[i].v,&Q[i].d,&Q[i].c);
    for (int i=q;i>=1;i--) Solve(Q[i].v,Q[i].d,Q[i].c);
    for (int i=1;i<=n;i++) printf("%d\n",f[i][0]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/beautiful_cxw/article/details/81082759