題目如下:
有一個由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]);
}