Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <bitset>
- #include <deque>
- #include <cmath>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <iostream>
- #include <list>
- #include <map>
- #include <queue>
- #include <set>
- #include <sstream>
- #include <stack>
- #include <string>
- #include <utility>
- #include <vector>
- #define fst first
- #define snd second
- #define all(x) (x).begin(), (x).end()
- #define clr( a , v ) memset( a , v , sizeof(a) )
- #define pb push_back
- #define mp make_pair
- #define sz size()
- #define FORN( i , s , n ) for( int i = s ; i < (int)(n) ; i++ )
- #define FOR( i , n ) FORN( i , 0 , n )
- #define FORIT(i,x) for( typeof x.begin() i = x.begin() ; i != x.end() ; i++ )
- #define trace(x) cerr << #x << ": " << x << endl;
- #define trace2(x, y) cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
- #define read ios::sync_with_stdio(false)
- using namespace std;
- typedef long long int64;
- typedef vector <int> vi;
- typedef pair <int,int> ii;
- typedef vector <string> vs;
- typedef vector <ii> vii;
- const int MAX = 20001;
- int low[MAX], d[MAX];
- int usd[MAX], prev[MAX], cnt;
- vector <int> adj[MAX];
- stack <ii> S;
- string ans;
- string sum( string a , string b ){
- string tmp = "";
- int carry = 0, d;
- if( a.sz > b.sz ){
- int n = a.sz - b.sz;
- FOR( i , n ) b += "0";
- }
- if( a.sz < b.sz ){
- int n = b.sz - a.sz;
- FOR( i , n ) a += "0";
- }
- FOR( i , a.sz ){
- d = ( a[i]-'0' ) + (b[i]-'0') + carry;
- carry = d / 10;
- d = d % 10;
- tmp += (d+'0');
- }
- if( carry ) tmp += "1";
- return tmp;
- }
- string mult( string a , int n ){
- if( n == 0 ) return "0";
- if( n == 1 ) return a;
- if( n % 2 ) return sum( a , mult( a , n-1 ) );
- string b = mult( a , n/2 );
- return sum( b , b );
- }
- void Outcomp( int u , int v ){
- pair <int,int> e;
- int edges = 0; set <int> vert;
- do{
- e = S.top(); S.pop();
- edges++;
- vert.insert(e.fst);
- vert.insert(e.snd);
- } while( e != mp( u , v ) );
- if( edges <= 1 ) return;
- if( edges == vert.sz ){
- ans = mult ( ans , ( edges + 1 ) );
- } else ans = "0";
- }
- void dfs( int u ){
- usd[u] = 1; cnt++;
- low[u] = d[u] = cnt;
- FOR( i , adj[u].sz ){
- int v = adj[u][i];
- if( !usd[v] ){
- S.push( mp( u , v ) );
- prev[v] = u; dfs( v );
- if( low[v] >= d[u] ) Outcomp( u , v );
- low[u] = min( low[u] , low[v] );
- }
- else if( prev[u] != v and d[v] < d[u] ){
- S.push( mp( u , v ) );
- low[u] = min( low[u] , d[v] );
- }
- }
- }
- int main(){
- int n, m;
- while( scanf("%d %d", &n, &m) != EOF ){
- FOR( i , n ) adj[i].clear();
- FOR( i , m ){
- int k, a , b;
- scanf("%d %d", &k, &a); a--;
- FOR( i , k-1 ){
- scanf("%d", &b); b--;
- adj[a].pb(b);
- adj[b].pb(a);
- a = b;
- }
- }
- cnt = 0;
- int comp = 0;
- clr( usd , 0 );
- clr( prev , -1 );
- ans = "1";
- FOR( i , n ){
- if( !usd[i] ){
- comp++;
- if( comp > 1 ){
- ans = "0"; break;
- }
- dfs(i);
- }
- }
- reverse( all (ans) );
- cout << ans << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment