HDU 5386 Cover

来源:互联网 发布:linux退出文件保存 编辑:程序博客网 时间:2024/06/06 09:50

有几种思路

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

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