有几种思路
倒过来做
枚举每个操作,然后判断该操作是不是最后一个操作。
判断是否是最后一个操作方法就是,除去已经用过的点,如果一排都相同的话,那就是最后一个操作。
如果是最后一个操作的话,就把所以的同样类型同样行列的废操作放在他们的前面。
#include <bits/stdc++.h>
using namespace std;
const int MAXN=105;
int n, m;
char str[2];
int a[MAXN][MAXN], b[MAXN][MAXN];
bool used[MAXN][MAXN];
int ans[505];
struct data{
int type, x, y, used;
}A[505];
bool islast(data S){
int x=S.x, y=S.y;
if(S.type){
for(int i=1; i<=n; i++){
if(!used[i][x]&&b[i][x]!=y){
return false;
}
}
for(int i=1; i<=n; i++){
used[i][x]=true;
}
}
else{
for(int i=1; i<=n; i++){
if(!used[x][i]&&b[x][i]!=y){
return false;
}
}
for(int i=1; i<=n; i++){
used[x][i]=true;
}
}
return true;
}
int main(){
int T; cin>>T;
for(int cs=1; cs<=T; cs++){
cin>>n>>m;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
scanf("%d",&a[i][j]);
used[i][j]=false;
}
}
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
scanf("%d",&b[i][j]);
}
}
for(int i=1, x, y; i<=m; i++){
scanf("%s%d%d",str,&A[i].x,&A[i].y);
if(str[0]=='L'){
A[i].type=1;
}
else{
A[i].type=0;
}
A[i].used=0;
}
int idx=0, lidx=m+1;
while(true){
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(!used[i][j]&&a[i][j]!=b[i][j]){
goto fail;
}
}
}
break;
fail:;
for(int i=1; i<=m; i++){
if(!A[i].used&&islast(A[i])){
A[i].used=true; ans[--lidx]=i;
for(int j=1; j<=m; j++) if(i!=j){
if(A[j].type==A[i].type&&A[j].x==A[i].x){
A[j].used=true;
ans[++idx]=j;
}
}
}
}
}
for(int i=1; i<=m; i++){
if(!A[i].used){
A[i].used=true;
ans[++idx]=i;
}
}
for(int i=1; i<=m; i++){
printf("%d%c",ans[i],i==m?'\n':' ');
}
}
return 0;
}
这个染色的过程一定会形成一个拓扑图
如果不在拓扑图里面的一定是废操作,然后所以得废操作可以全部放到最前面,而且对后面的操作没有任何影响。如果废操作会染到后面正确操作影响不到的点,那么这个染色的过程一定是不可行的(题意说一定可行)
于是你就判断,对于每一个点,我们将 可以影响到它的操作但是不能染到正确颜色的操作 往 可以影响到它的操作并且染到正确颜色的操作 连边。对于连边,只有L和H之间连边,形成一个二分图。
然后所有没有连边的点,就是废操作,直接输出。
然后再跑一个拓扑排序…..
// whn6325689
// Mr.Phoebe
// http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62
#define speed std::ios::sync_with_stdio(false);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;
#define CLR(x,y) memset(x,y,sizeof(x))
#define CPY(x,y) memcpy(x,y,sizeof(x))
#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))
#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
template <class T>
inline void write(T n)
{
if(n < 0)
{
putchar('-');
n = -n;
}
int len = 0,data[20];
while(n)
{
data[len++] = n%10;
n /= 10;
}
if(!len) data[len++] = 0;
while(len--) putchar(data[len]+48);
}
//-----------------------------------
const int MAXN=555;
bool vis[MAXN];
int now[111][111],tar[111][111];
int deg[MAXN];
struct Node
{
int x,y,id;
bool operator < (const Node& b)const
{
if(x!=b.x) return x<b.x;
if(y!=b.y) return y<b.y;
return id<b.id;
}
Node(int x=0,int y=0,int id=0):x(x),y(y),id(id){}
}H[MAXN],L[MAXN];
int n,m;
int cnH,cnL;
int g[MAXN][MAXN];
pii que[MAXN];
int ans[MAXN],tot;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
CLR(vis,0);cnH=cnL=tot=0;
CLR(g,0);CLR(deg,0);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&now[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&tar[i][j]);
char op[5];
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%s %d %d",op,&x,&y);
if(op[0]=='H')
{
H[cnH].x=x;H[cnH].y=y;H[cnH].id=i;cnH++;
}
else
{
L[cnL].x=x;L[cnL].y=y;L[cnL].id=i;cnL++;
}
}
sort(H,H+cnH);sort(L,L+cnL);
for(int i=1;i<=n;i++)
{
int pos=lower_bound(H,H+cnH,Node(i,-1,-1))-H;
for(int j=1;j<=n;j++)
{
int pos2=lower_bound(L,L+cnL,Node(j,-1,-1))-L;
for(int k=pos;k<cnH && H[k].x==i;k++)
if(H[k].y==tar[i][j])
{
for(int t=pos2;t<cnL && L[t].x==j;t++)
if(L[t].y!=tar[i][j])
{
vis[H[k].id]=true;vis[L[t].id]=true;
g[L[t].id][H[k].id]=1;
deg[H[k].id]++;
}
}
for(int k=pos2;k<cnL && L[k].x==j;k++)
if(L[k].y==tar[i][j])
{
for(int t=pos;t<cnH && H[t].x==i;t++)
if(H[t].y!=tar[i][j])
{
vis[L[k].id]=true;vis[H[t].id]=true;
g[H[t].id][L[k].id]=1;
deg[L[k].id]++;
}
}
}
}
int head=0,tail=0;
for(int i=0;i<cnH;i++)
if(vis[H[i].id] && deg[H[i].id]==0)
que[tail++]=mp(0,H[i].id);
else if(!vis[H[i].id])
ans[tot++]=H[i].id;
for(int i=0;i<cnL;i++)
if(vis[L[i].id] && deg[L[i].id]==0)
que[tail++]=mp(1,L[i].id);
else if(!vis[L[i].id])
ans[tot++]=L[i].id;
while(head<tail)
{
pii u=que[head++];
ans[tot++]=u.second;
if(u.first==0)
{
for(int i=0;i<cnL;i++)
if(g[u.second][L[i].id])
{
deg[L[i].id]--;
if(deg[L[i].id]==0)
que[tail++]=mp(1,L[i].id);
}
}
else if(u.first==1)
{
for(int i=0;i<cnH;i++)
{
if(g[u.second][H[i].id])
{
deg[H[i].id]--;
if(deg[H[i].id]==0)
que[tail++]=mp(0,H[i].id);
}
}
}
}
for(int i=0;i<tot;i++)
printf("%d%c",ans[i],i==tot-1?'\n':' ');
}
return 0;
}