[bzoj3979] [WF2012]infiltration

  膜了半天ccz大爷的题解...随机调整好神啊。。

  大概就是把点随机一下,按随机后的顺序控制,顺便删掉无用点。

  做完一次后,把一个已被控制的点丢回去,然后继续随机顺序做下去。。。

  为啥我要尝试的次数比ccz大爷多那么多啊QAQ

  实测一次丢多个点回去反而不好...

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxn=79;
 8 int st[maxn],b[maxn];
 9 int mp[maxn][maxn],cd[maxn],deg[maxn];
10 int i,j,k,n,m,ans;
11 char s[maxn];
12  
13  
14 inline void run(){
15     int i,top=n,now,numb=0;register int j;
16     memset(deg,0,(n+1)<<2);
17     for(i=1;i<=n;i++)
18         for(st[i]=i,j=1;j<=cd[i];j++)deg[mp[i][j]]++;
19     for(int t=20;t;t--){
20         for(i=2;i<=top;i++)swap(st[i],st[rand()%(i-1)+1]);
21         for(i=1;i<=top;i++){
22             now=st[i];
23             for(j=1;j<=cd[now];j++)if(deg[mp[now][j]]<=1)break;
24             if(j>cd[now]){
25                 for(j=1;j<=cd[now];j++)deg[mp[now][j]]--;
26                 b[++numb]=now;
27                 st[i]=st[top],i--,top--;
28             }
29         }
30         for(i=1;i<=n;i++)if(!deg[i])return;
31         if(top<ans)ans=top;
32         if(numb){
33             now=rand()%numb+1;
34             for(j=1;j<=cd[b[now]];j++)deg[mp[b[now]][j]]++;
35             st[++top]=b[now];
36             b[now]=b[numb],numb--;
37         }
38     }
39 }
40 int main(){
41     int T=0;srand(1844677);
42     while(scanf("%d",&n)!=EOF){
43         T++;
44         for(i=1;i<=n;i++){
45             scanf("%s",s+1);s[i]='1';
46             cd[i]=0;
47             for(j=1;j<=n;j++)if(s[j]=='1')mp[i][++cd[i]]=j;
48         }
49         ans=n;
50         for(i=100;i;i--)run();
51         printf("Case %d: %d\n",T,ans);
52     }
53 }
View Code

 

posted @ 2016-07-05 21:12  czllgzmzl  阅读(190)  评论(0编辑  收藏  举报