首页
Github
管理

PTA-球队“食物链”强力剪枝

题目大意:给定一张图,求长度为n的环。
注意,球队可以在主场赢,也可以在客场赢,这样的话,能A四个点,第四个点t,用canwin[i]数组存放i是否能赢球队1,用来判断是否剩下的球队能赢球队1,这样才能构成环。

#include<bits/stdc++.h>
using namespace std;
char buf[1<<17],*L=buf,*R=buf;
inline char gc() {
    return L==R&&(R=(L=buf)+fread(buf,1,1<<17,stdin),L==R)?EOF:*L++;
}
template<typename T>
inline void read(T&x) {
    int flag=x=0;
    char ch=gc();
    while (ch<'0'||ch>'9')
        flag|=ch=='-',ch=gc();
    while (ch>='0'&&ch<='9')
        x=(x<<3)+(x<<1)+ch-48,ch=gc();
    if(flag)
        x=-x;
}
bool vis[30];
int to[30],n,len[30];
bool M[30][30],win[30];
vector<int>mmp[22];
void print() {
    for(int i=0,j=1;i<n;++i,j=to[j]){
        printf("%d",j);
        if(to[j])putchar(' ');
    }
    exit(0);
}
void dfs(int i,int sum) {
    if(sum==n) {
        for(int j=0; j<len[i]; ++j)
            if(mmp[i][j]==1)
                print();
        return;
    }
    for(int j=0; j<len[i]; ++j) {
        if(!vis[mmp[i][j]]) {
            vis[mmp[i][j]]=1;
            int canwin=0;
            for(int k=1;!canwin&&k<=n;++k){
                if(!vis[k])canwin|=win[k];
            }
            to[i]=mmp[i][j];
            if(canwin||sum==n-1)dfs(mmp[i][j],sum+1);
            to[i]=0;
            vis[mmp[i][j]]=0;
        }
    }
}
int main() {
    freopen("in.txt","r",stdin);
    read(n);
    for(int i=1; i<=n; ++i) {
        for(int j=1; j<=n; ++j) {
            char ch=gc();
            if(ch=='W')M[i][j]=1;
            else if(ch=='L')M[j][i]=1;
        }
        gc();
    }
    for(int i=1; i<=n; ++i) {
        for(int j=1; j<=n; ++j) {
            if(M[i][j]) {
                mmp[i].push_back(j);
                ++len[i];
                if(j==1)win[i]=1;
            }
        }
        gc();
    }
    vis[1]=1;
    dfs(1,1);
    cout<<"No Solution";
    return 0;
}
posted @ 2020-12-16 17:05  肆之月  阅读(100)  评论(0编辑  收藏  举报