HDU 5386 Cover

有几种思路

倒过来做
枚举每个操作,然后判断该操作是不是最后一个操作。
判断是否是最后一个操作方法就是,除去已经用过的点,如果一排都相同的话,那就是最后一个操作。
如果是最后一个操作的话,就把所以的同样类型同样行列的废操作放在他们的前面。

#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;
} 

你可能感兴趣的:(HDU 5386 Cover)