zoukankan      html  css  js  c++  java
  • 「CodePlus 2017 12 月赛」白金元首与独舞

    description

    题面

    data range

    [1 leq T leq 10, 1 leq n, m leq 200 , 0 leq k leq min(nm, 300) ]

    solution

    矩阵树定理

    求无向图的生成树个数

    度数矩阵-邻接矩阵

    去掉一行一列求行列式

    为了保证精度可以辗转相除

    这里是模意义下的

    const int mod=998244353;
    int a[305][305];
    il int gauss(int n){
    	RG int ans=1;
    	for(RG int i=2;i<=n;i++){
    		for(RG int j=i+1;j<=n;j++)
    			while(a[j][i]){
    				RG int t=a[i][i]/a[j][i];
    				for(RG int k=i;k<=n;k++)dec(a[i][k],1ll*t*a[j][k]%mod);
    				swap(a[i],a[j]);if(ans)ans=mod-ans;
    			}
    		ans=1ll*ans*a[i][i]%mod;
    	}
    	if(ans<0)ans+=mod;return ans;
    }
    

    有向图的外向(父亲指向儿子)生成树个数

    对于每条边((u,v))(a[v][v]++,a[u][v]--)(把度数看成入度)

    然后直接求行列式即可

    这题的解法

    首先判掉无解

    然后我们发现题目中每个空格方向的选择决定了空格之间的到达关系

    于是这道题目变成了一个求内向生成树个数的题

    套上矩阵树定理即可

    code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define FILE "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=2000010;
    const dd pi=acos(-1);
    const int inf=2147483645;
    const ll INF=1e18+1;
    const ll P=100000;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	srand(time(NULL)+rand());
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    }
    
    int n,m,p[305][305],kx[305],ky[305];
    int id[305][305],tag[305][305],t[100010],cnt,tot;
    int a[305][305];
    int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
    il void init(){
    	memset(id,0,sizeof(id));
    	memset(tag,0,sizeof(tag));
    	memset(t,0,sizeof(t));
    	memset(a,0,sizeof(a));
    	n=read();m=read();tot=1;cnt=0;
    	for(RG int i=1,c;i<=n;i++)
    		for(RG int j=1;j<=m;j++){
    			a[i][j]=tag[i][j]=id[i][j]=c=0;
    			while(c!='L'&&c!='R'&&c!='U'&&c!='D'&&c!='.')c=getchar();
    			if(c=='L')p[i][j]=0;if(c=='R')p[i][j]=1;
    			if(c=='U')p[i][j]=2;if(c=='D')p[i][j]=3;
    			if(c=='.'){p[i][j]=4;id[i][j]=++tot;kx[tot]=i;ky[tot]=j;}
    		}
    }
    
    il bool work(){
    	for(RG int i=1;i<=n;i++)
    		for(RG int j=1;j<=m;j++)
    			if(!id[i][j]&&!tag[i][j]){
    				RG int x=i,y=j,w=p[i][j];cnt++;
    				RG int xx=x+dx[w],yy=y+dy[w];
    				while(!id[x][y]&&!tag[x][y]&&x>0&&y>0&&x<=n&&y<=m){
    					tag[x][y]=cnt;x=xx;y=yy;w=p[x][y];xx=x+dx[w];yy=y+dy[w];
    				}
    				if(id[x][y])t[cnt]=id[x][y];
    				else if(x<1||y<1||x>n||y>m)t[cnt]=1;
    				else if(tag[x][y]==cnt)return 0;
    				else if(tag[x][y])t[cnt]=t[tag[x][y]];
    			}
    	return 1;
    }
    
    il void upd(int &a,int b){a+=b;if(a>=mod)a-=mod;}
    il void dec(int &a,int b){if(b)upd(a,mod-b);}
    il int gauss(int n){
    	RG int ans=1;
    	for(RG int i=2;i<=n;i++){
    		for(RG int j=i+1;j<=n;j++)
    			while(a[j][i]){
    				RG int t=a[i][i]/a[j][i];
    				for(RG int k=i;k<=n;k++)dec(a[i][k],1ll*t*a[j][k]%mod);
    				swap(a[i],a[j]);if(ans)ans=mod-ans;
    			}
    		ans=1ll*ans*a[i][i]%mod;
    	}
    	if(ans<0)ans+=mod;return ans;
    }
    il int solve(){
    	for(RG int i=2;i<=tot;i++)
    		for(RG int w=0;w<=3;w++){
    			RG int xx=kx[i]+dx[w],yy=ky[i]+dy[w];
    			RG int u=t[tag[xx][yy]],v=i;
    			if(id[xx][yy])u=id[xx][yy];
    			if(xx<1||yy<1||xx>n||yy>m)u=1;
    			if(u==v||!u)continue;
    			a[v][v]++;if(!a[u][v])a[u][v]=mod;a[u][v]--;
    		}
    	return gauss(tot);
    }
    
    int main()
    {
    	RG int T=read();
    	while(T--){
    		init();
    		if(!work()){puts("0");continue;}
    		else printf("%d
    ",solve());
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    grunt in webstorm
    10+ Best Responsive HTML5 AngularJS Templates
    响应式布局
    responsive grid
    responsive layout
    js event bubble and capturing
    Understanding Service Types
    To add private variable to this Javascript literal object
    Centering HTML elements larger than their parents
    java5 新特性
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9497567.html
Copyright © 2011-2022 走看看