ZOJ 3687 The Review Plan I 容斥原理

一道纯粹的容斥原理题!!不过有一个trick,就是会出现重复的,害我WA了几次!!

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>
#define ll long long
#define mod 55566677
using namespace std;
int p[52],ans;
int m,n;
bool visd[52],visc[52],vis[52][52];
struct point
{
    int a,b;
}q[30];
void dfs(int s,int i,int f)
{
    ans=(ans+f*p[n-s])%mod;
    while(ans<0) ans=(ans+mod)%mod;
    for(int k=i+1;k<m;k++){
        if(!visd[q[k].a]&&!visc[q[k].b]){
            visd[q[k].a]=1;
            visc[q[k].b]=1;
            dfs(s+1,k,-f);
            visd[q[k].a]=0;
            visc[q[k].b]=0;
        }
    }
}
int main()
{
    int i,a,b,j;
    p[0]=p[1]=1;
    for(i=2;i<=50;i++) p[i]=((ll)p[i-1]*i)%mod;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(vis,0,sizeof(vis));
        memset(visd,0,sizeof(visd));
        memset(visc,0,sizeof(visc));
        for(j=i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            if(!vis[a][b]){
                vis[a][b]=1;
                q[j].a=a;
                q[j++].b=b;
            }
        }
        m=j;
        ans=0;
        for(i=0;i<m;i++){
            visd[q[i].a]=1;
            visc[q[i].b]=1;
            dfs(1,i,1);
            visd[q[i].a]=0;
            visc[q[i].b]=0;
        }
        ans=(p[n]-ans)%mod;
        while(ans<0) ans=(ans+mod)%mod;
        printf("%d
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3405387.html