思路:
- 最小生成树。
使用 Kruskal 不停 MLE,改成 Prim 才过掉。- Kruskal:不能写递归的FIND,会爆栈MLE;几处小优化都要加,很容易TLE。
- Prim:随便写写就过了。
- 另有不解之处,见代码。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 755;
int N,M;
int num;
int par[maxn];
struct NODE{
int x;
int y;
}node[maxn];
struct EDGE{
int u , v , w;
friend bool operator < (EDGE a , EDGE b){
return a.w < b.w;
}
}edge[maxn * maxn / 2];int cnt;
void ADDEDGE(int u,int v,int w){
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].w = w;
cnt++;
}
void INIT(){
cnt = 0;
num = 0;
memset(par , -1 , sizeof(par));
return ;
}
int FIND(int i){
while(par[i] != -1)
i = par[i];
return i;
}
void UNION(int l,int r){
int parl = FIND(l);
int parr = FIND(r);
if(parl == parr)
return ;
par[parl] = parr;
return ;
}
void KRUSKAL(){
sort(edge , edge + cnt);
for(int i=0;i<cnt;i++){
if(num == N-1)
break;
int u = edge[i].u;
int v = edge[i].v;
int w = edge[i].w;
int parl = FIND(u);
int parr = FIND(v);
if(parl != parr){
UNION(u,v);
num++;
printf("%d %d\n" , u , v);
}
}
return ;
}
int main(){
INIT();
scanf("%d" , &N);
for(int i=1;i<=N;i++)
scanf("%d%d" , &node[i].x , &node[i].y);
scanf("%d" , &M);
for(int i=1;i<=M;i++){
int u,v;
scanf("%d%d" , &u , &v);
UNION(u,v);
}
for(int i=1;i<=N;i++)
for(int j=i+1;j<=N;j++){
if(FIND(i) == FIND(j))
continue;
int w = (node[i].x - node[j].x)*(node[i].x - node[j].x) + (node[i].y - node[j].y)*(node[i].y - node[j].y);
ADDEDGE(i,j,w);
}
KRUSKAL();
return 0;
}
#include <iostream>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 755;
int N,M;
int mp[maxn][maxn];
int dis[maxn];
bool vis[maxn];
struct ORD{
int x;
int y;
}ord[maxn];
struct NODE{
int id;
int par;
int dis;
friend bool operator > (NODE a , NODE b)
{
return a.dis > b.dis ;
}
NODE(int id,int par,int dis) : id(id) , par(par) , dis(dis) {} ;
};
priority_queue <NODE , vector<NODE> , greater<NODE> > Q;
void INIT(){
memset(vis , 0 , sizeof(vis));
memset(dis , INF , sizeof(dis));
memset(mp , 0 , sizeof(mp));
return ;
}
void PRIM(){
dis[1] = 0;
Q.push(NODE(1 ,-1, 0)) ;
while(Q.size()){
NODE cur = Q.top() ; Q.pop() ;
int id = cur.id;
if(vis[id])
continue;
vis[id] = true;
if(dis[id]){
cout<<cur.par<<' '<<id<<endl;
}
for(int i=1;i<=N;i++)
if(!vis[i] && dis[i] > mp[id][i]){
dis[i] = mp[id][i];
Q.push(NODE(i , id , dis[i]));
}
}
return ;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
INIT();
cin>>N;
for(int i=1;i<=N;i++)
cin>>ord[i].x>>ord[i].y;
for(int i=1;i<=N;i++)
for(int j=i+1;j<=N;j++)
mp[i][j] = mp[j][i] = (ord[i].x-ord[j].x)*(ord[i].x-ord[j].x) + (ord[i].y-ord[j].y)*(ord[i].y-ord[j].y);
cin>>M;
for(int i=1;i<=M;i++){
int l,r;
cin>>l>>r;
mp[l][r] = mp[r][l] = 0;
}
PRIM();
return 0;
}