第一次打Div 1,感觉还是挺难的。。把基础题打完就日常划水了。。。。
A. Arpa's loud Owf and Mehrdad's evil plan
题目大意: 有n个人,每个人有一个后继,求在进行多少次传递后第i 个人跟第j个人对话的同时,第j个人也能跟第i个人对话(允许自己与自己对话)。$1leq n leq 100$ 这
题意花了我好多时间啊。。说白了就是要找环咯,把每条环求出来然后看环长度是不是偶数,是的话就除2,然后就个最大公约数就行了。
Code:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 #define maxn 110 7 typedef long long ll; 8 ll gcd(ll x,ll y){ 9 if (y==0) return x; 10 return gcd(y,x%y); 11 } 12 int a[maxn],b[maxn],n; 13 int main(){ 14 scanf("%d",&n); 15 for (int i=1;i<=n;i++) scanf("%d",a+i); 16 ll ans=1; 17 for (int i=1;i<=n;i++) { 18 memset(b,0,sizeof(b)); 19 int l=1; 20 int t=i; 21 while (!b[t]) { 22 b[t]=l; 23 l++; 24 t=a[t]; 25 } 26 if (b[t]!=1) { 27 printf("-1 "); 28 return 0; 29 } 30 l--; 31 if (l%2==0) l/=2; 32 ans=ans*1ll*((l)/gcd(ans,l)); 33 } 34 cout<<ans<<endl; 35 return 0; 36 }
B. Arpa's weak amphitheater and Mehrdad's valuable Hoses
题目大意:给定n群女生,每群女生要么只能邀请一个女生要么就要全部邀请,求在满足重量限制的情况下的最大收益。
分组背包模型,可以直接$O((m+n)w)$解决,令$f[i][j]$为前i组重量为j的最大收益,则每个$f[i]$内就是最好的。
Code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 #define maxn 1010 9 vector<int> e[maxn]; 10 int w[maxn],b[maxn]; 11 bool bo[maxn]; 12 int f[maxn][maxn]; 13 int num[maxn][maxn]; 14 inline void addedge(int x,int y){ 15 e[x].push_back(y);e[y].push_back(x); 16 } 17 int n,m,W,N; 18 void bfs(int u){ 19 static queue<int> q; 20 q.push(u); 21 bo[u]=1; 22 N++; 23 while (!q.empty()){ 24 u=q.front();q.pop(); 25 num[N][0]++; 26 num[N][num[N][0]]=u; 27 for (int i=0;i<e[u].size();i++){ 28 if (bo[e[u][i]]) continue; 29 q.push(e[u][i]); 30 bo[e[u][i]]=1; 31 } 32 } 33 return ; 34 } 35 int sumb[maxn],sumw[maxn]; 36 int main(){ 37 scanf("%d%d%d",&n,&m,&W); 38 for (int i=1;i<=n;i++) scanf("%d",w+i); 39 for (int j=1;j<=n;j++) scanf("%d",b+j); 40 for (int i=1;i<=m;i++) { 41 int x,y; 42 scanf("%d%d",&x,&y); 43 addedge(x,y); 44 } 45 for (int i=1;i<=n;i++) 46 if (!bo[i]) bfs(i); 47 for (int i=1;i<=N;i++) { 48 for (int j=0;j<=W;j++) f[i][j]=f[i-1][j]; 49 for (int j=1;j<=num[i][0];j++) { 50 for (int k=W;k>=w[num[i][j]];k--) 51 f[i][k]=max(f[i-1][k-w[num[i][j]]]+b[num[i][j]],f[i][k]); 52 sumb[i]+=b[num[i][j]]; 53 sumw[i]+=w[num[i][j]]; 54 } 55 for (int j=W;j>=sumw[i];j--) 56 f[i][j]=max(f[i-1][j-sumw[i]]+sumb[i],f[i][j]); 57 } 58 printf("%d ",f[N][W]); 59 return 0; 60 }
C. Arpa’s overnight party and Mehrdad’s silent entering
题目大意:有n对情侣坐在一张圆桌上吃饭,有两种食品,要求每个人和男女朋友不吃同一种东西,同时要求没有连续3个人吃同一种东西。
这题太坑了。。要把条件收束一点才能做。。。把没有连续的3个人吃同一种东西变成1跟2吃不同,3跟4吃不同...,然后就变成一个二分图模型就可以2-set解决了。。。(为什么是个二分图可以自己想一想)
Code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define pb push_back 8 #define maxn 201000 9 vector<int> e[maxn]; 10 int n,x,y; 11 int col[maxn],b[maxn]; 12 int dfs(int x,int y){ 13 col[x]=y; 14 b[x]=1; 15 for (int i=0;i<e[x].size();i++) 16 if (!b[e[x][i]]) 17 dfs(e[x][i],y^1); 18 return 0; 19 } 20 int a[maxn],c[maxn]; 21 int main(){ 22 scanf("%d",&n); 23 for (int i=1;i<=n;i++) { 24 scanf("%d%d",&x,&y); 25 a[i]=x;c[i]=y; 26 e[x].pb(y); 27 e[y].pb(x); 28 } 29 for (int i=1;i<=n;i++) { 30 e[i*2].pb(i*2-1); 31 e[i*2-1].pb(i*2); 32 } 33 for (int i=1;i<=n*2;i++) if (!b[i]) dfs(i,1); 34 for (int i=1;i<=n;i++) printf("%d %d ",col[a[i]]+1,col[c[i]]+1); 35 return 0; 36 }