题目链接:https://www.luogu.com.cn/problem/P3825
我太蠢了呀。
题意读错想半天。蠢的跟猪一样。
最后看了题解才晓得题意读错了,猪,你为何这么蠢。
先来个题意知识:
#include"stdio.h"
#include"string.h"
#include"vector"
#include"algorithm"
using namespace std;
#define OK printf("\n");
#define exit return 0;
const int N = 1e6 * 2 + 1010;
const int M = 2 * N;
int read()
{
int f=1,x=0;
char ss=getchar();
while(ss<‘0‘||ss>‘9‘){if(ss==‘-‘)f=-1;ss=getchar();}
while(ss>=‘0‘&&ss<=‘9‘){x=x*10+ss-‘0‘;ss=getchar();}
return f*x;
}
int head[N],ver[M],Next[M],tot;int n,m,num,top,cnt;
int dfn[N],low[N],id[110];int limit = 0;
int Stack[N],ins[N],c[N];
int s[N]; char str[N];
int X[N],Y[N]; char cx[N],cy[N];
void add(int x,int y){
ver[++ tot] = y; Next[tot] = head[x];
head[x] = tot;
}
void tarjan(int x){
dfn[x] = low[x] = ++ num;
Stack[++ top] = x; ins[x] = 1;
for(int i = head[x]; i; i = Next[i])
if(!dfn[ver[i]]) {
tarjan(ver[i]);
low[x] = min(low[x],low[ver[i]]);
} else if(ins[ver[i]])
low[x] = min(low[x],dfn[ver[i]]);
if(dfn[x] == low[x]){
cnt ++; int y;
do{
y = Stack[top --];ins[y] = 0;
c[y] = cnt;
} while(x != y);
}
}
void Build_edge()
{
for(int i = 1; i <= m; i ++){
if(str[X[i]] == cx[i]) continue;
if(str[Y[i]] == cy[i]) {
if(cx[i] == ‘C‘ || (cx[i] == ‘B‘ && str[X[i]] == ‘C‘)) {
add(X[i] + n,X[i]); //printf("%d -> %d\n",X[i] + n,X[i]);
} else {
add(X[i],X[i] + n); //printf("%d -> %d\n",X[i],X[i] + n);
}
continue;
}
int v1 = (cy[i] == ‘C‘ || (cy[i] == ‘B‘ && str[Y[i]] == ‘C‘)) ? 1 : 0;
int v2 = (cx[i] == ‘C‘ || (cx[i] == ‘B‘ && str[X[i]] == ‘C‘)) ? 1 : 0;
add(X[i] + n * (v2),Y[i] + n * v1);
add(Y[i] + n * (v1 ^ 1),X[i] + n * (v2 ^ 1));
// printf("%d -> %d\n",X[i] + n *(v2),Y[i] + n * v1);
// printf("%d -> %d\n",Y[i] + n * (v1 ^ 1),X[i] + n * (v2 ^ 1));
}
return ;
}
void init()
{
num = 0; memset(ins,0,sizeof(ins));
cnt = 0; tot = 0; top = 0;
memset(low,0,sizeof(low)); memset(c,0,sizeof(c));
memset(dfn,0,sizeof(dfn));memset(Stack,0,sizeof(Stack));
memset(head,0,sizeof(head));
}
void solve(){
int mark = 1;
for(int i = 0; i < (1 << limit); i ++){
init();mark = 1;
for(int j = 1; j <= limit; j ++){
str[id[j]] = (i & (1 << (j - 1))) ? ‘A‘ : ‘B‘;
}
Build_edge();
for(int i = 1; i <= n * 2; i ++){
if(!dfn[i]) tarjan(i);
}
for(int i = 1; i <= n; i ++)
if(c[i] == c[i + n]) {mark = 0; break;}
if(mark == 0) continue;
for(int i = 1; i <= n; i ++){
if(c[i] < c[i + n]){
if(str[i] == ‘A‘) printf("B");
else printf("A");
} else {
if(str[i] == ‘C‘) printf("B");
else printf("C");
}
}
return ;
}
printf("-1"); return ;
}
int main()
{
int d;
scanf("%d%d",&n,&d);
scanf("%s",str + 1);
for(int i = 1; i <= n; i ++)
{
if(str[i] == ‘x‘) id[++ limit] = i;
else str[i] -= 32;
}
m = read();
for(int i = 1; i <= m; i ++){
scanf("%d %c %d %c",&X[i],&cx[i],&Y[i],&cy[i]);
}
solve();
return 0;
}
原文:https://www.cnblogs.com/yrz001030/p/12428049.html
小 L 对游戏有一些特殊的要求,这些要求可以用四元组 (i,hi,j,hj)来描述,表示若在第i场使用型号为hi的车子,则第j场游戏要使用型号为hj的车子。
这句话的意思应该是在第i场选择了hi的时候,则第j场必须选择hj。
但是是建了反向边的呢?也就是说: 若两个都可用,则从i向j连边,表示若选i,则一定选j,同时从j′向i′连边,这里表示若没有选j,则一定没有选i。
为啥没有选hj,则i那个位置不能选hi呢?题目只是说i选择了hi,则j必须选择hj呀。我相信有部分同学会有这个困惑。
解释: