poj 1751 Highways (最小生成树,空间卡常数有毒啊)

poj1751题目链接

题意:一开始有一些边,然后添加一些边,使得代价之和最小。

思路:先把给定的边merge掉。。然后计算其余可以添加的边。。。接下来就是最小生成树。。。

然而因为多开了一个750*750的数组空间被卡了常。。。毫无人性。。。。

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年07月13日 星期三 19时53分29秒
  4File Name :code/poj/1751.cpp
  5 ************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=755;
 34int n;
 35int m;
 36int om;
 37pi ans[N*N];
 38bool conc[N*N];
 39int f[N];
 40struct Edge
 41{
 42    int u,v;
 43    double w;
 44
 45    bool operator < (Edge b)const
 46    {
 47	return w<b.w;
 48    }
 49}edge[N*N];
 50
 51
 52
 53struct point
 54{
 55    double  x,y;
 56
 57    void input()
 58    {
 59	scanf("%lf%lf",&x,&y);
 60    }
 61
 62    double dis( point b)
 63    {
 64	double res ;
 65	res = (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y);
 66	return sqrt(res);
 67    }
 68}p[N];
 69
 70void init()
 71{
 72    for ( int i = 1 ; i <= n ; i++) f[i] = i;
 73}
 74
 75int root ( int x)
 76{
 77    if (x!=f[x] ) f[x] = root (f[x]);
 78    return f[x];
 79}
 80
 81void merge( int x,int y)
 82{
 83    int rx = root (x);
 84    int ry = root (y);
 85    if (rx==ry) return ;
 86    f[rx] = ry;
 87}
 88int main()
 89{
 90#ifndef  ONLINE_JUDGE 
 91    freopen("code/in.txt","r",stdin);
 92#endif
 93
 94    cin>>n;
 95    init();
 96    for ( int i = 1 ; i <= n ; i++) p[i].input();
 97    cin>>m;
 98    om = m;
 99    int cnt = 0 ;
100    for ( int i = 1 ; i <= m ; i++)
101    {
102	int u,v;
103	scanf("%d%d",&u,&v);
104	if (root(u)==root(v)) continue;
105	merge(u,v);
106	cnt++;
107    }
108
109    m = 0 ;
110    for ( int i = 1 ; i <= n ; i++)
111	for ( int j = 1 ; j <= n ; j++)
112	    if (i<j)
113	    {
114		m++;
115		edge[m].u =i;
116		edge[m].v = j ;
117		edge[m].w = p[i].dis(p[j]);
118	    }
119
120    sort(edge+1,edge+m+1);
121    double mst = 0 ;
122    int num = 0 ;
123    for ( int i = 1; i <= m ; i++)
124    {
125	int u = edge[i].u;
126	int v = edge[i].v;
127	double w = edge[i].w;
128	if (cnt>=n-1) break;
129	if (root(u)==root(v)) continue;
130	//	    cout<<"u:"<<u<<" v:"<<v<<" w:"<<w<<endl;
131	merge(u,v);
132	cnt++;
133	num++;
134	mst+=w;
135	ans[num]=make_pair(u,v);
136    }
137    //	cout<<"cnt:"<<cnt<<endl;
138    sort(ans+1,ans+num+1);
139
140    for ( int i = 1 ;i <= num ; i++)
141	cout<<ans[i].fst<<" "<<ans[i].sec<<endl;
142
143
144
145#ifndef ONLINE_JUDGE  
146    fclose(stdin);
147#endif
148    return 0;
149}