gfojzy_13 腦洞記搜

題目如下:

Splatter Painting

有一個由N個頂點編號爲1到N和M個邊緣組成的簡單的無向圖。最初,所有頂點都以彩色0繪製。第i個邊緣雙向連接兩個頂點ai和bi。每個邊的長度爲1。

Squid在此圖上執行了Q操作。在第i個操作中,他以顏色ci重新繪製距離頂點vi的距離內的所有頂點。

在Q操作後查找每個頂點的顏色。

1≤N,M,Q≤105
1≤ai,bi,vi≤N
ai≠bi
0≤di≤10
1≤ci≤105

分析

本題的暴力可以輕鬆寫出,注意到一個點只有最後一次染色有效,所以可以從後往前做,如果已被染色則跳過
發現可以記錄距此點染色的結點的最大距離d[i]
舉個例子:
d[6]=1,d[1]=2
然後就a了

完整ac代碼1

if(e[y]<z-1)Q.push((Dis){y,z-1});//判斷是否應該入隊,則不用bo【】數組標記是否在隊列中
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define N 100010
using namespace std;
struct Dis{
    int x,z;
};
queue<Dis>Q;
int a[N],c[N],d[N],e[N],f[N],num,h[N],n,m,p,q,t,col;
struct Edge{
    int p,q,n;
}b[N*2];
void ljb(int p,int q){
    b[++num].n=h[p];
    h[p]=num;
    b[num].p=p;
    b[num].q=q;
}
void Bfs(){
    int x,y,z;
    while(!Q.empty()){
        x=Q.front().x; z=Q.front().z; Q.pop(); 
//      printf("%d %d\n",x,z);
        if(!f[x])f[x]=col;
        e[x]=max(e[x],z);
        if(z==0)continue;
        for(int i=h[x];i!=0;i=b[i].n){
            y=b[i].q;
            if(e[y]<z-1)Q.push((Dis){y,z-1});
        }
    }
}
int main(){
//  freopen("data.txt","r",stdin);
    memset(e,-1,sizeof(e));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&p,&q);
        ljb(p,q);
        ljb(q,p);
    }
    scanf("%d",&t);
    for(int i=1;i<=t;i++)scanf("%d%d%d",&a[i],&d[i],&c[i]);
    for(int i=t;i>=1;i--){
        if(e[a[i]]>=d[i])continue;
        col=c[i];
        Q.push((Dis){a[i],d[i]});
        Bfs();
    }
//  for(int i=1;i<=n;i++)printf("%d %d\n",i,e[i]);
    for(int i=1;i<=n;i++)printf("%d\n",f[i]);
}

完整ac代碼2

比代碼1效率低
多了一個bo【】標記是否入隊(其實是多餘的)

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define N 100010
using namespace std;
struct Dis{
    int x,z;
};
queue<Dis>Q;
int a[N],c[N],d[N],e[N],f[N],num,h[N],n,m,p,q,t,col;
bool bo[N];
struct Edge{
    int p,q,n;
}b[N*2];
void ljb(int p,int q){
    b[++num].n=h[p];
    h[p]=num;
    b[num].p=p;
    b[num].q=q;
}
void Bfs(){
    int x,y,z;
    while(!Q.empty()){
        x=Q.front().x; z=Q.front().z; Q.pop(); 
        printf("%d %d\n",x,z);
        if(!f[x])f[x]=col;
        if(z<=e[x]||z==0)continue;
        e[x]=z;
        for(int i=h[x];i!=0;i=b[i].n){
            y=b[i].q;
            if(!bo[y]){
                Q.push((Dis){y,z-1});
                bo[y]=1;
            }
        }
    }
}
int main(){
//  freopen("data.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&p,&q);
        ljb(p,q);
        ljb(q,p);
    }
    scanf("%d",&t);
    for(int i=1;i<=t;i++)scanf("%d%d%d",&a[i],&d[i],&c[i]);
    for(int i=t;i>=1;i--){
        memset(bo,0,sizeof(bo));
        if(e[a[i]]>=d[i])continue;
        col=c[i];
        Q.push((Dis){a[i],d[i]});
        bo[a[i]]=1;
        Bfs();
    }
    for(int i=1;i<=n;i++)printf("%d\n",f[i]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章