有一个拥有n个城市的国家。这个国家由n-1条边连接起来。有一天国家发生叛乱。叛军已占领了一些城市。如果叛军占领的城市中,存在两个城市之间有边直接相连,则称这种情况是坏的。现在并不知道叛军占领了那些城市,问有多少种情况是坏的?
Input第1行一个正整数n,表示国家的大小
第2行到第n行,每行两个数字x, y,表示x,y之间有一条边。
Output一个整数表示方案数,答案对(1e9+7)取模
Sample Input2
1 2
Sample Output1
HINT1 <= n <= 1e5,1<=x,y<=n,x≠y
以下题解搬运自出题人yyl:“直接做dp应该也是可以的。但是补集转化之后,我们发现其实就是问从点集V中选出若干个点构成点集S,满足S是一个独立集(即S中任意两点没有边直接相连)。设方案数为x。答案就是2^n -x。”
补充:最后输出2^n -x时因为涉及取模,要注意处理负数的情况。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define ll long long 5 using namespace std; 6 const int N=1e5+5; 7 const int mod=1e9+7; 8 int n,x,y,cnt,head[N]; 9 struct edge{int to,next;}e[N*2];10 ll ansn=1,dp[N][2];11 int read()12 {13 int x=0,f=1;char c=getchar();14 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}15 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}16 return x*f;17 }18 void ins(int u,int v){cnt++;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}19 void solve(int x,int fa)20 {21 dp[x][1]=dp[x][0]=1;22 for(int i=head[x];i;i=e[i].next)23 {24 int to=e[i].to;25 if(to==fa)continue;26 solve(to,x);27 dp[x][0]=(dp[to][0]+dp[to][1])%mod*dp[x][0]%mod;28 dp[x][1]=dp[to][0]*dp[x][1]%mod;29 }30 }31 int main()32 {33 n=read();34 for(int i=1;i<n;i++)35 {36 x=read();y=read();37 ins(x,y);ins(y,x);38 }39 solve(1,0);40 for(int i=1;i<=n;i++)ansn=(ansn*2)%mod;41 printf("%lld",((ansn-dp[1][0]-dp[1][1])%mod+mod)%mod);42 return 0;43 } View Code
转载于:https://www.cnblogs.com/zsnuo/p/7169713.html