| ||||||||||
Forest ProgramTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 562 Accepted Submission(s): 193 Problem Description The kingdom of Z is fighting against desertification these years since there are plenty of deserts in its wide and huge territory. The deserts are too arid to have rainfall or human habitation, and the only creatures that can live inside the deserts are the cactuses. In this problem, a cactus in desert can be represented by a cactus in graph theory.
Input The first line contains two non-negative integers n, m (1 ≤ n ≤ 300 000, 0 ≤ m ≤ 500 000), denoting the number of vertices and the number of edges in the given graph.
Output Output a single line containing a non-negative integer, denoting the answer modulo 998244353. |
题目大意:现在给你一个仙人掌图,仙人掌图的定义就是每一条边最多在一个简单环上,然后问你把现在他给你的这个图弄成森林的删边的方案数,
思路:
首先我们考虑的是每一个环上的数量,应该是除了不删的情况都可以,如果这个环是由K个边的,那么也就是
个,每环都乘起来,然后就是裸露在外面的没有成环的边了,这些边是没有任何限制的也就是
个,乘起来就可以了
比赛的时候想到了点双,我们是用点双过的,但是很耗费时间,感觉还是搜索好一点,最起码时间上没问题了,
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#define ll long long
using namespace std;
const int maxn=3e5+10;
const ll mod=998244353;
int vis[maxn];
vector<int >G[maxn];
int n,m;
int ans,num;
ll quick_pow(ll a,ll b)
{
ll res=1;
while(b>0)
{
if(b%2)
res=(res*a)%mod;
a=(a*a)%mod;
b/=2;
}
return res;
}
void DFS(int u,int fa)
{
vis[u]=vis[fa]+1;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(fa==v) continue;
if(vis[v]==0)
DFS(v,u);
else if(vis[u]>vis[v])
{
int temp=vis[u]-vis[v]+1;
num+=temp;
/*cout<<"u,v :"<<u<<" "<<v<<endl;
cout<<"vis u,v :"<<vis[u]<<" "<<vis[v]<<endl;;
cout<<"quick_pow:"<<quick_pow(2,temp)-1<<endl;*/
ans=(ans%mod*(quick_pow(2,temp)-1)%mod)%mod;
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
G[i].clear();
ans=1,num=0;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
DFS(i,0);
}
/*for(int i=1;i<=n;i++)
cout<<vis[i]<<" ";
cout<<endl;*/
ans=(ans%mod*(quick_pow(2,m-num))%mod)%mod;
cout<<ans<<endl;
}
}