トピック:http://poj.org/problem?id=3164
コマンドネットワーク
制限時間:1000msのメモリ制限:131072K
合計提出:16037受理:4623
説明
言葉の長期的な戦争の後、腕に戦争は最終的にlittlekenのとKnuthOceanの王国の間で勃発します。KnuthOceanの力によって突然の暴力的な攻撃はlittlekenのコマンドネットワークの完全な失敗をレンダリングしています。暫定ネットワークはすぐに構築する必要があります。littleken受注はプロジェクトの責任を取るためにスヌーピー。
細部にまで研究の状況では、スヌーピーが最も緊急のポイントが破壊されたネットワーク内のすべての切断ノードに到達するためにlittenkenのコマンドを有効にすることであり、一方向の通信ネットワークを構築する計画を決定すると考えています。ノードは、平面上に分布しています。littlekenのコマンドは、別のノードAからノードBに直接送達することができるようになっている場合、ワイヤは、2つのノードを結ぶ線分に沿って構築されなければなりません。それは戦時中ではなく、すべてのノード対の間だからワイヤを構築することができます。スヌーピーは、建設は非常にすぐに行うことができるように、配線の最短全長を必要とする計画を望んでいます。
入力
入力は、いくつかのテストケースが含まれています。各テストケースは、2つの整数N(N 100以下)、破壊されたネットワーク内のノードの数、及びM(M≤104)、ワイヤが構築できるとの間のノードのペアの数を含む行から始まります。次のN行はそれぞれのノードのデカルト座標を与え、順序対Xi及びYIを含みます。次いで、M線をiとj 1及びワイヤーを意味N(両端を含む)の間には、後者に前者から一方向コマンド送達のためにノードiとノードjとの間で構築することができるそれぞれ含む2つの整数を辿ります。littlekenの本社は、常にファイルの末尾にノード1のプロセスに位置しています。
出力
各テストケースのために、出力を正確小数点過去二桁のワイヤの最短全長を含む一行。そのようなネットワークが存在しないことのケースでは、単に出力「貧しいスヌーピー」。
サンプル入力
4 6
0 6
4 6
0 0
7 20
1 2
1 3
2 3
3 4
3 1
3 2
4 3
0 0
1 0
0 1
1 2
1 3
4 1
2 3
サンプル出力
31.19
貧しいスヌーピー
アイデア:
参照してくださいhttp://blog.csdn.net/shuangde800/article/details/8039359
すなわち:*役に立たない側から、削除、
接続1図の決意を、解が直接通信しない場合、そうでなければ少なくとも一つの溶液を。
2.すべてのノードは、回答などの無環なかった、容易に入手可能なプレ[]、[]ミネソタ州を、記録、最短辺を見つけるために、
リング3、もしリング[]の縁にANS収縮点+ =エッジ、エッジ[]エッジを縮小する点- =ミネソタ州[x]は、図に示すように、(*不要な側から、削除);
非環式の4リピート、休憩
コード:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
int n,m;
struct node{
double x,y;
}p[1005];
struct edge{
int x,y;
double v;
}q[1005*105];
double in[1005];
int pre[1005];
int vis[1005],id[1005];
double inf=99999999.9;
double solve()
{
double ret=0.0;
int nn=n;
int rt=1;
while(1)
{
for(int i=1;i<=nn;i++) in[i]=inf;
for(int i=1;i<=m;i++)
{
if(q[i].x!=q[i].y&&in[q[i].y]>q[i].v)
{
pre[q[i].y]=q[i].x;
in[q[i].y]=q[i].v;
}
}
for(int i=1;i<=nn;i++)
{
if(i==rt) continue;
if(in[i]==inf) return -1;
}
int cnt=0;
memset(id,-1,sizeof(id));
memset(vis,-1,sizeof(vis));
in[rt]=0;
for(int i=1;i<=nn;i++)
{
ret+=in[i];
int now=i;
while(now!=rt&&vis[now]!=i&&id[now]==-1)
{
vis[now]=i;
now=pre[now];
}
if(now!=rt&&id[now]==-1)
{
cnt++;
for(int nex=pre[now];nex!=now;nex=pre[nex]) id[nex]=cnt;
id[now]=cnt;
}
}
if(cnt==0) break;
for(int i=1;i<=nn;i++)
if(id[i]==-1) id[i]=++cnt;
for(int i=1;i<=m;i++)
{
int xx=q[i].x;
int yy=q[i].y;
q[i].x=id[xx];
q[i].y=id[yy];
if(id[xx]!=id[yy]) q[i].v-=in[yy];
}
nn=cnt;
rt=id[rt];
}
return ret;
}
double dis(node a, node b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].x,&q[i].y);
if(q[i].x!=q[i].y) q[i].v=dis(p[q[i].x],p[q[i].y]);
else q[i].v=inf;
}
double ans=solve();
if(ans==-1) printf("poor snoopy\n");
else printf("%.2f\n", ans);
}
}