题目链接:https://pan.baidu.com/s/1_vsHfMI_qO-9IDxmFLkHfg 密码: uza8
T1:
小奥的一笔画,判连通性,查奇偶点即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; inline long long read() { long long f=1,ans=0;char c; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } long long t; long long n,m; struct node{ long long x,y; long long nex; }s[200001]; long long head[100001]; long long cnt=1; void add(long long a,long long b) { s[cnt].x=a,s[cnt].y=b; s[cnt].nex=head[a];head[a]=cnt++; } long long xx[100001]; long long book[100001]; bool f; void dfs(long long bh,long long ans) { for(long long i=head[bh];i!=-1;i=s[i].nex) { if(book[s[i].y]==0) { book[s[i].y]=1; dfs(s[i].y,ans+1); } } return; } int main() { t=read(); while(t--) { memset(head,-1,sizeof(head)); memset(book,0,sizeof(book)); memset(s,0,sizeof(s)); memset(xx,0,sizeof(xx)); n=read(),m=read(); cnt=1; for(long long i=1;i<=m;i++) { long long u=read(),v=read(); add(u,v),add(v,u); xx[u]++,xx[v]++; } f=true; book[1]=1; dfs(1,1); for(int i=1;i<=n;i++) if(book[i]==0) {f=false;break;} if(f==false) { cout<<"NO"<<endl; continue; } bool ssss=true;long long ans=0; for(long long i=1;i<=n;i++) { if(xx[i]%2==1) ans++; if(xx[i]==0) { ssss=false; cout<<"NO"<<endl; break; } if(ans>2) { ssss=false; cout<<"NO"<<endl; break; } } if(ssss) cout<<"YES"<<endl; } return 0; } /* 1 8 9 1 2 1 3 2 3 3 7 3 8 3 4 4 5 5 6 3 8 */
T2:
状压dp,dp[i][j]:i在二进制有0的位数表示这个人希望已被破灭,1表示这个希望仍在。j表示前j个人(被期望活的人m)。总体表示在逆元之后的值
显然,dp[i][j+1]=(dp[i][j]*inv)%mod(j+1这个人还活着)
而j+1死的时候:dp[i&t1][j+1]=(dp[i][j]*inv)%mod //ti表示除了希望破灭的人的二进制数,从而表示出来j+1死后别人的希望
因为每种可能都占1/2,所以每次取前面dp[i][j]的1/2
dp[(1<<n)-1][0]=1,因为这是每一个都有希望
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define inv 499122177 #define mod 998244353 #define low_bit(x) x&-x using namespace std; inline long long read() { long long f=1,ans=0;char c; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } long long cx(long long s) { long long c=0; while(s!=0) { long long sry=low_bit(s); s-=sry; c++; } return c; } long long n,m,dp[35][100001],ans[40]; long long s[6][100001]; int main() { n=read(),m=read(); for(long long i=1;i<=n;i++) { long long x=read(); long long xx; for(long long j=1;j<=x;j++) xx=read(),s[i][xx]=1; } dp[(1<<n)-1][0]=1; for(long long i=0;i<m;i++) { for(long long j=(1<<n)-1;j>=0;j--) { dp[j][i+1]+=(dp[j][i]*inv)%mod; dp[j][i+1]%=mod; long long t=(1<<n)-1; for(long long k=1;k<=n;k++) if(s[k][i+1]==1) t-=(1<<k-1); dp[j&t][i+1]+=(dp[j][i]*inv)%mod; dp[j&t][i+1]%=mod; } } for(long long i=0;i<=(1<<n)-1;i++) { (ans[cx(i)]+=dp[i][m])%=mod; } for(long long i=0;i<=n;i++) printf("%d ",ans[i]); }