2 条题解

  • 0
    @ 2025-10-8 16:50:36
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 2e4 + 10;
    const int P = 10000;
    
    struct hipr {
    	int len;
    	int a[3010];
    	hipr() { 
    		memset(a, 0, sizeof(a)); 
    		len = 1; 
    	}
    } ans;
    
    hipr operator*(hipr hp, int x) {
    	hipr res;
    	res.len = hp.len;
    	
    	for (int i = 1; i <= res.len; i++) {
    		res.a[i] = hp.a[i] * x;
    	}
    	for (int i = 1; i <= res.len; i++) {
    		res.a[i + 1] += res.a[i] / P;
    		res.a[i] %= P;
    	}
    	
    	int i = res.len;
    	while (res.a[i + 1] > 0) {
    		i ++;
    		res.a[i + 1] += res.a[i] / P;
    		res.a[i] %= P;
    	}
    	res.len = i;
    	
    	return res;
    }
    
    int k[N];
    vector<int> G[N];
    int tsp, dfn[N], low[N], dep[N];
    bool flag;
    
    void tarjan(int x, int xfa) {
    	dfn[x] = low[x] = ++tsp;
    	dep[x] = dep[xfa] + 1;
    	int sum = 0;
    	for (int y : G[x]) if (y != xfa) {
    		if (!dfn[y]) {
    			tarjan(y, x);
    			low[x] = min(low[x], low[y]);
    			
    			if (low[y] < dfn[x]) {     //区别在这里,要让环上的每个点都知道有环
    			// 可以自己模拟样例 2看看 
    				sum ++;
    			}
    		}
    		else {
    			low[x] = min(low[x], dfn[y]);
    		}
    		
    		if (dfn[x] > dfn[y]) {
    			sum ++;
    			ans = ans * (dep[x] - dep[y] + 2); 
    		}
    	}
    	
    	if (sum > 1) {
    		flag = 0;
    	}
    }
    
    int main () {
    	ios::sync_with_stdio(False);
    	cin.tie(0);
    	
    	int n, m;
    	cin >> n >> m;
    	
    	for (int i = 1; i <= m; i++) {
    		cin >> k[i];
    		
    		int pre;
    		cin >> pre;
    		for (int j = 2; j <= k[i]; j++) {
    			int x;
    			cin >> x;
    			G[pre].push_back(x);
    			G[x].push_back(pre);
    			pre = x;
    		}
    	}
    	
    	tsp = 0; memset (dfn, 0, sizeof(dfn));
    	memset (low, 0, sizeof(low));
    	ans.len = 1;
    	ans.a[1] = 1;
    	dep[0] = 0;
    	flag = 1;
    	
    	tarjan(1, 0);
    	
    	if (tsp != n) {
    		flag = 0;
    	}
    	
    	if (!flag) {
    		cout << '0' << "\n";
    	}
    	else {
    		cout << ans.a[ans.len];
    		
    		for (int i = ans.len - 1; i >= 1; i--) {
    			cout << setw(4) << setfill('0') << ans.a[i];
    		}
    		cout << "\n";
    	}
    	
    	return 0;
    }
    
    • 0
      @ 2025-10-8 16:50:20

      scy不能过样例的代码:


      #include<bits/stdc++.h>
      using namespace std;
      const int N=2e4+10;
      

      struct node { int a[2100], len; node(){memset(a,0,sizeof(a));len=1;} }ans; node operator (node no,int x) { for(int i=1;i<=no.len;i++)no.a[i]=x; for(int i=1;i<=no.len;i++){no.a[i+1]+=no.a[i]/10000;no.a[i]%=10000;} int i=no.len; while(no.a[i+1]>0) { no.a[i+1]+=no.a[i]/10000; no.a[i]%=10000; i++; } no.len=i; return no; }

      vector<int>G[N]; int tsp,dfn[N],low[N],dep[N]; bool flag;

      void tarjan(int x,int xfa) { dfn[x]=low[x]=++tsp; int num=0; for(int y:G[x])if(y!=xfa) { if(!dfn[y]) { dep[y]=dep[x]+1; tarjan(y,x); low[x]=min(low[x],low[y]); } else low[x]=min(low[x],dfn[y]); if(dfn[x]>dfn[y]) { num++; ans=ans*(dep[x]-dep[y]+2); } } if(num>1)flag=0; } int main() { int n,m;scanf("%d%d",&n,&m); while(m--) { int k,x,y;scanf("%d%d",&k,&x);k--; while(k--) { scanf("%d",&y); G[x].push_back(y);G[y].push_back(x); x=y; } } tsp=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low)); memset(dep,0,sizeof(dep)); ans.a[1]=1;flag=1;tarjan(1,0); if(tsp!=n)flag=0; if(!flag)printf("0"); else { printf("%d",ans.a[ans.len]); for(int i=ans.len-1;i>=1;i--)printf("%04d",ans.a[i]); } printf("\n"); return 0; }

      </p>


      hansang的正确代码:

      #include<bits/stdc++.h>
      using namespace std;
      

      const int N = 2e4 + 10; const int P = 10000;

      struct hipr { int len; int a[3010]; hipr() { memset(a, 0, sizeof(a)); len = 1; } } ans;

      hipr operator*(hipr hp, int x) { hipr res; res.len = hp.len;

      for (int i = 1; i &lt;= res.len; i++) {
      	res.a[i] = hp.a[i] * x;
      }
      for (int i = 1; i &lt;= res.len; i++) {
      	res.a[i + 1] += res.a[i] / P;
      	res.a[i] %= P;
      }
      
      int i = res.len;
      while (res.a[i + 1] &gt; 0) {
      	i ++;
      	res.a[i + 1] += res.a[i] / P;
      	res.a[i] %= P;
      }
      res.len = i;
      
      return res;
      

      }

      int k[N]; vector<int> G[N]; int tsp, dfn[N], low[N], dep[N]; bool flag;

      void tarjan(int x, int xfa) { dfn[x] = low[x] = ++tsp; dep[x] = dep[xfa] + 1; int sum = 0; for (int y : G[x]) if (y != xfa) { if (!dfn[y]) { tarjan(y, x); low[x] = min(low[x], low[y]);

      		if (low[y] &lt; dfn[x]) {     //区别在这里,要让环上的每个点都知道有环
      		// 可以自己模拟样例 2看看 
      			sum ++;
      		}
      	}
      	else {
      		low[x] = min(low[x], dfn[y]);
      	}
      	
      	if (dfn[x] &gt; dfn[y]) {
      		sum ++;
      		ans = ans * (dep[x] - dep[y] + 2); 
      	}
      }
      
      if (sum &gt; 1) {
      	flag = 0;
      }
      

      }

      int main () { ios::sync_with_stdio(False); cin.tie(0);

      int n, m;
      cin &gt;&gt; n &gt;&gt; m;
      
      for (int i = 1; i &lt;= m; i++) {
      	cin &gt;&gt; k[i];
      	
      	int pre;
      	cin &gt;&gt; pre;
      	for (int j = 2; j &lt;= k[i]; j++) {
      		int x;
      		cin &gt;&gt; x;
      		G[pre].push_back(x);
      		G[x].push_back(pre);
      		pre = x;
      	}
      }
      
      tsp = 0; memset (dfn, 0, sizeof(dfn));
      memset (low, 0, sizeof(low));
      ans.len = 1;
      ans.a[1] = 1;
      dep[0] = 0;
      flag = 1;
      
      tarjan(1, 0);
      
      if (tsp != n) {
      	flag = 0;
      }
      
      if (!flag) {
      	cout &lt;&lt; '0' &lt;&lt; "\n";
      }
      else {
      	cout &lt;&lt; ans.a[ans.len];
      	
      	for (int i = ans.len - 1; i &gt;= 1; i--) {
      		cout &lt;&lt; setw(4) &lt;&lt; setfill('0') &lt;&lt; ans.a[i];
      	}
      	cout &lt;&lt; "\n";
      }
      
      return 0;
      

      }

      </p>
      • 1

      *【仙人掌】无向连通图的支撑子图个数[SHOI2006]仙人掌

      信息

      ID
      446
      时间
      3000ms
      内存
      128MiB
      难度
      8
      标签
      递交数
      34
      已通过
      6
      上传者