传送门
板子题= =(有一点点变化而已)
给每一个公司建一个树= =
也就是所有的东东都再加一维而已= =
怎么判“任何公司不能控制连接同一个站点的两条以上的电缆”这个条件呢?
记一下每个点的度即可(煞笔吧
注意这个度也是每个公司一个哦
其他的没有什么变化了吧
判边用map
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int max_n=8005;
const int max_c=105;
struct hp{
bool flag;
int y,x;
};
int n,m,c,t,x,y,z;
int ch[max_c][max_n][2],f[max_c][max_n],reverse[max_c][max_n];
int sum[max_c][max_n];
int strack[max_n];
inline int get(int x,int con){
return ch[con][ f[con][x] ][1]==x;
}
inline int Is_Root(int x,int con){
return ch[con][ f[con][x] ][0]!=x&&ch[con][ f[con][x] ][1]!=x;
}
/* inline void update(int x,int con){ } */
inline void pushdown(int x,int con){
if (x&&reverse[con][x]){
swap(ch[con][x][0],ch[con][x][1]);
if (ch[con][x][0]) reverse[con][ ch[con][x][0] ]^=1;
if (ch[con][x][1]) reverse[con][ ch[con][x][1] ]^=1;
reverse[con][x]=0;
}
}
inline void rotate(int x,int con){
int old=f[con][x],oldf=f[con][old],which=get(x,con);
if (!Is_Root(old,con))
ch[con][oldf][ ch[con][oldf][1]==old ]=x;
f[con][x]=oldf;
ch[con][old][which]=ch[con][x][which^1];
f[con][ ch[con][old][which] ]=old;
ch[con][x][which^1]=old;
f[con][old]=x;
// update(old,con);
// update(x,con);
}
inline void splay(int x,int con){
int temp=0;
strack[++temp]=x;
for (int i=x; !Is_Root(i,con); i=f[con][i])
strack[++temp]=f[con][i];
for (int i=temp;i>=1;--i)
pushdown(strack[i],con);
for (int fa; !Is_Root(x,con); rotate(x,con))
if (!Is_Root(fa=f[con][x],con))
rotate( (get(x,con)==get(fa,con)) ?fa:x ,con);
}
inline void Access(int x,int con){
int t=0;
for (; x; t=x,x=f[con][x]){
splay(x,con);
ch[con][x][1]=t;
// update(x,con);
}
}
inline void Reverse(int x,int con){
Access(x,con);
splay(x,con);
reverse[con][x]^=1;
}
inline void Link(int x,int y,int con){
Reverse(x,con);
f[con][x]=y;
splay(x,con);
sum[con][x]++;
sum[con][y]++;
}
inline hp Cut(int x,int y,int con){
hp ans;
Reverse(x,con);
Access(y,con);
splay(y,con);
if (ch[con][y][0]==x)
return ans=(hp){true,y,x};
else return ans=(hp){false,0,0};
}
inline int Find(int x,int con){
Access(x,con);
splay(x,con);
while (ch[con][x][0])
x=ch[con][x][0];
return x;
}
int main(){
scanf("%d%d%d%d",&n,&m,&c,&t);
for (int i=1;i<=m;++i){
scanf("%d%d%d",&x,&y,&z);
Link(x,y,z);
}
for (int i=1;i<=t;++i){
scanf("%d%d%d",&x,&y,&z);
hp pd;
pd=Cut(x,y,z);
if (pd.flag){
printf("Already owned.\n");
continue;
}
for (int j=1;j<=c;++j)
if (j!=z){
pd=Cut(x,y,j);
if (pd.flag){
if (sum[z][x]==2||sum[z][y]==2){
printf("Forbidden: monopoly.\n");
break;
}
if (Find(x,z)==Find(y,z)){
printf("Forbidden: redundant.\n");
break;
}
printf("Sold.\n");
ch[j][pd.y][0]=f[j][pd.x]=0;
sum[j][y]--;
sum[j][x]--;
Link(x,y,z);
break;
}
}
if (!pd.flag){
printf("No such cable.\n");
continue;
}
}
}
map大法好!