CF659FPolycarp and Hay(并查集,bfs)

Posted myx12345

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF659FPolycarp and Hay(并查集,bfs)相关的知识,希望对你有一定的参考价值。

题意:

构造一个矩阵,使得:

矩阵所有格子中数字都小于等于原矩阵,并且至少有一个元素和原矩阵相等,

构造的矩阵除了0以外的数字必须联通并且相等,矩阵中元素之和为K。

n,m<=1e3,1<=K<=1e18

思路:

From https://blog.csdn.net/morejarphone/article/details/51037918

对每个格子的数字进行排序,那么一个格子的数字最多能够填的格子数就是他上下左右格子能够填的格子

数的和,这个可以用并查集来维护

然后枚举每个格子,如果这个格子的数字能够整除k并且这个格子能够填的个数足够,就可以从这个格子出发

bfs一遍找到需要的格子

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second s
 19 #define MP make_pair
 20 #define N   1100
 21 #define M   1100000
 22 #define MOD 1000000007
 23 #define eps 1e-8 
 24 #define pi acos(-1)
 25 #define oo 2e9+1
 26 
 27 int dx[4]={1,-1,0,0},
 28     dy[4]={0,0,-1,1};
 29     
 30 struct node
 31 {
 32     int x,y;
 33     ll z;
 34 }b[M],q[M];
 35 
 36 ll a[N][N],K;
 37 int vis[N][N],num[N][N],f[M],size[M],n,m;
 38     
 39 
 40 int read()
 41 { 
 42    int v=0,f=1;
 43    char c=getchar();
 44    while(c<48||57<c) {if(c==-) f=-1; c=getchar();}
 45    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 46    return v*f;
 47 }
 48 
 49 
 50 bool cmp(node a,node b)
 51 {
 52     return a.z>b.z;
 53 } 
 54 
 55 int find(int k)
 56 {
 57     if(f[k]!=k) f[k]=find(f[k]);
 58     return f[k];
 59 }
 60 
 61 
 62 void bfs(int x,int y,ll cnt)
 63 {
 64     int t=0;
 65     int w=1;
 66     q[1].x=x; q[1].y=y;
 67     memset(vis,0,sizeof(vis));
 68     vis[x][y]=1;
 69     cnt--;
 70     while(t<=w&&cnt)
 71     {
 72         t++;
 73         int nowx=q[t].x;
 74         int nowy=q[t].y;
 75         vis[nowx][nowy]=1;
 76         for(int i=0;i<4;i++)
 77         {
 78             int tx=nowx+dx[i];
 79             int ty=nowy+dy[i];
 80             if(!tx||tx>n||!ty||ty>m||vis[tx][ty]) continue;
 81             if(a[tx][ty]>=a[x][y])
 82             {
 83                 vis[tx][ty]=1;
 84                 q[++w].x=tx;
 85                 q[w].y=ty;
 86                 cnt--;
 87                 if(cnt<=0) break;
 88             }
 89         }
 90     }
 91     for(int i=1;i<=n;i++)
 92     {
 93         for(int j=1;j<=m;j++)
 94         {
 95             if(vis[i][j]) printf("%lld",a[x][y]);
 96              else printf("0");
 97             if(j<m) printf(" ");
 98         }
 99         printf("
");
100     }
101 }
102         
103         
104 int main()
105 {
106     //freopen("cf659f.in","r",stdin);
107     //freopen("cf659f.out","w",stdout);
108     scanf("%d%d%lld",&n,&m,&K);
109     for(int i=1;i<=n;i++)
110      for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]); 
111     int tot=0;
112     for(int i=1;i<=n;i++)
113      for(int j=1;j<=m;j++) 
114      {
115          num[i][j]=(i-1)*m+j;
116          size[num[i][j]]=1;
117          f[num[i][j]]=num[i][j];
118          b[++tot].x=i;
119          b[tot].y=j;
120          b[tot].z=a[i][j];
121      }
122     sort(b+1,b+tot+1,cmp);
123 
124     memset(vis,0,sizeof(vis));
125     for(int i=1;i<=tot;i++)
126     {
127          vis[b[i].x][b[i].y]=1;
128          for(int j=0;j<4;j++)
129          {
130              int x=b[i].x+dx[j];
131             int y=b[i].y+dy[j];
132             if(x&&x<=n&&y&&y<=m&&vis[x][y])
133             {
134                 int p=find(num[b[i].x][b[i].y]);
135                 int q=find(num[x][y]);
136                 if(p!=q)
137                 {
138                     f[q]=p;
139                     size[p]+=size[q];
140                 }
141             }
142          }
143     }
144     
145 //    for(int i=1;i<=n;i++)
146 //     for(int j=1;j<=m;j++) printf("%d
",size[num[i][j]]);
147 
148     int ans=0;
149     for(int i=1;i<=n;i++)
150     {
151         for(int j=1;j<=m;j++)
152            if(K%a[i][j]==0&&size[num[i][j]]>=K/a[i][j])
153            {
154                printf("YES
");
155                bfs(i,j,K/a[i][j]);
156                ans=1; break;
157            }
158         if(ans) break;
159     }
160     if(!ans) printf("NO");
161      
162 }
163     
164     
165 
166 
167             
168         

 

以上是关于CF659FPolycarp and Hay(并查集,bfs)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #346 (Div. 2) (659A,659B,659C,659D(几何叉乘),659E(并查集))

Out of Hay(poj2395)(并查集)

洛谷P1547 Out of Hay 最小生成树 并查集

CF #738(div2)D2. Mocha and Diana (Hard Version)(贪心,并查集)

CF #738(div2)D1. Mocha and Diana (Easy Version)(暴力,并查集)

CF766DMahmoud and a Dictionary(并查集)