zoukankan      html  css  js  c++  java
  • bzoj3659Which Dreamed It

    Solution

    (BEST) 定理,套用完成后,由于每一个路径都对应了 (deg_1) 这么多的不同起始方向的情况数,乘上去就可以了。

    Code

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline void read (int&a)
    {
    	a = 0; char k = getchar(); int f = 1;
    	while (k > '9' || k < '0') { if (k == '0') f = -1; k = getchar(); }
    	while (k >= '0' && k <= '9') { a = a * 10 + k - '0'; k = getchar (); }
    	a *= f;
    }
    
    const int N = 200 + 5, mod = 1000003;
    inline int plu (int u, int v) { return u + v >= mod ? u + v - mod : u + v; }
    inline int sub (int u, int v) { return u - v < 0 ? u - v + mod : u - v; }
    inline int mul (int u, int v) { return 1LL * u * v % mod; }
    int a[N][N], n, outdeg[N], indeg[N], fac[200000 + 5];
    
    inline int Guass ()
    {
    //	for (int i = 1; i <= n; ++i, puts (""))
    //		for (int j = 1; j <= n; ++j)
    //			printf ("%d ", a[i][j]);
    	int ans = 1;
    	for (int i = 1; i <= n - 1; ++i)
    	{
    		for (int j = i + 1; j <= n - 1; ++j)
    		{
    			while (a[j][i])
    			{
    				int l = a[i][i] / a[j][i];
    				for (int k = i; k <= n - 1; ++k)
    					a[i][k] = sub (a[i][k], mul (l, a[j][k]));
    				swap (a[i], a[j]);
    				ans = mod - ans;
    			}
    		}
    		ans = mul (ans, a[i][i]);
    	}
    	return ans;
    }
    
    int main ()
    {
    	fac[0] = 1;
    	for (int i = 1; i <= 200000; ++i)
    		fac[i] = 1LL * fac[i - 1] * i % mod;
    	while (scanf ("%d", &n) == 1 && n)
    	{
    		memset (a, 0, sizeof a);
    		memset (outdeg, 0, sizeof outdeg);
    		memset (indeg, 0, sizeof indeg);
    		for (int i = 1; i <= n; ++i)
    		{
    			int s; read (s);
    			for (int j = 1; j <= s; ++j)
    			{
    				int k; read (k);//i -> k
    				a[i][k]--;
    				a[i][i]++;
    				indeg[k]++;
    				outdeg[i]++;
    			}
    		}
    		if (n == 1) { printf ("%d
    ", fac[ indeg[1] ]); continue; }//不用特判也可以过
    		for (int i = 1; i <= n; ++i)
    			for (int j = 1; j <= n; ++j)
    				a[i][j] = sub (a[i][j], 0);
    		bool flag = false;
    		for (int i = 1; i <= n; ++i)
    			if (indeg[i] != outdeg[i])
    				{ printf ("0
    "), flag = true; break; }
    		if (flag) continue;
    		int ans = 1;
    		for (int i = 1; i <= n; ++i)
    			ans = mul (ans, fac[ indeg[i] - 1 ]);
    		ans = mul (ans, mul (Guass(), indeg[1]));
    		printf ("%d
    ", ans);
    	}
    	return 0;
    }
    

    Conclusion

    又开始错各种细节了。

    比如矩阵忘了去掉某一行,而是直接 (n) 行计算。

    注意某一行我写了不用特判也可以,因为高斯消元里面返回的因该是 (1)

  • 相关阅读:
    docker study
    安卓学习征文 -- 自己定义标题栏
    ftp server来源分析20140602
    poj1251--Kruskal
    cocos2d-x 3.0rc1 创建project
    创建序列和相应的视图
    华为OJ: 公共字符串计算
    LeetCode:Minimum Depth of Binary Tree
    webservice发送字符串
    高德地图由哪几部分组成
  • 原文地址:https://www.cnblogs.com/ChiTongZ/p/11618446.html
Copyright © 2011-2022 走看看