Graph: The Edge connecting edge right around a vertex is the edge of the absolute value of the difference between two vertices.
Because there are multiple points that need to be "cast", it is equivalent to the minimum value of the longest edge within T for each such point, that is, multiple queries.
If the longest side is the smallest, it must be that the minimal spanning tree is not running. But if you do this for each vertex, it will certainly be TLE.
Therefore, consider handling the answers to all the questions at a time.
When the Union query set connects two point sets to an edge, if the points and <t of the two points set do not affect the query points in the two sets.
If the number of points and> = T of the two point sets, if the original number of points in the (B) set is <t, the query points in the (B) Set match the meaning of the question, the maximum value is the edge weight of the current edge. Of course, kruscal is greedy, so this value is the smallest.
In addition to maintaining connectivity, the query set also maintains the number of vertices of a set and the number of inquiry points of a set.
P.s. Because noip uses ** devc ++ 4.9.9.2, I tried it with a bid. It is too **, there is no matching in brackets, and debugging and indentation and hotkeys are cumbersome.
P.s. p.s. The runtime interface is not stuck. Add for (;); At the end. Do not forget to delete it before submitting it !!!!!! Otherwise, TLE will not lose sight (<--- angry flag ).
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define N 601 5 typedef long long ll; 6 int Abs(const int &x){return x<0 ? (-x) : x;} 7 struct Edge 8 { 9 int u,v,w;10 Edge(const int &a,const int &b,const int &c){u=a;v=b;w=c;}11 Edge(){}12 }edges[(N*N)<<2];13 bool operator < (const Edge &a,const Edge &b){return a.w<b.w;}14 int n,m,K,fa[N*N],rank[N*N],a[N][N],nm,num[N][N],en,cnt[N*N],tot,ask_sum[N*N];15 bool b[N*N];16 ll ans;17 void init(){for(int i=1;i<=nm;i++) fa[i]=i,cnt[i]=1,ask_sum[i]=b[i];}18 int findroot(int x)19 {20 if(x==fa[x]) return x;21 int rt=findroot(fa[x]);22 fa[x]=rt;23 return rt;24 }25 void Union(const int &U,const int &V)26 {27 if(rank[U]<rank[V]) fa[U]=V,cnt[V]+=cnt[U],ask_sum[V]+=ask_sum[U];28 else29 {30 fa[V]=U; cnt[U]+=cnt[V]; ask_sum[U]+=ask_sum[V];31 if(rank[U]==rank[V]) rank[U]++;32 }33 }34 int main()35 {36 scanf("%d%d%d",&n,&m,&K); nm=n*m;37 for(int i=1;i<=n;i++)38 for(int j=1;j<=m;j++)39 {40 scanf("%d",&a[i][j]);41 num[i][j]=++en;42 } en=0;43 for(int i=1;i<=n;i++)44 for(int j=1;j<=m;j++)45 scanf("%d",&b[num[i][j]]);46 for(int i=1;i<=n;i++)47 for(int j=1;j<=m;j++)48 {49 if(i!=n) edges[++en]=Edge(num[i][j],num[i+1][j],Abs(a[i][j]-a[i+1][j]));50 if(j!=m) edges[++en]=Edge(num[i][j],num[i][j+1],Abs(a[i][j]-a[i][j+1]));51 }52 sort(edges+1,edges+en+1); init();53 for(int i=1;i<=en;i++)54 {55 int f1=findroot(edges[i].u),f2=findroot(edges[i].v);56 if(f1!=f2)57 {58 if(cnt[f1]+cnt[f2]>=K)59 {60 if(cnt[f1]<K) ans+=((ll)edges[i].w*(ll)ask_sum[f1]);61 if(cnt[f2]<K) ans+=((ll)edges[i].w*(ll)ask_sum[f2]);62 }63 Union(f1,f2); tot++;64 if(tot==nm-1) break;65 }66 }67 printf("%I64d\n",ans);68 return 0;69 }
[Kruscal] [Minimum Spanning Tree] [offline] distance between rogu p2266 and love