标签:
朱刘算法模板题
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #define INF 1<<30 using namespace std; int n,m; struct node { double x,y; }nod[110<<1]; double in[110<<1] ; int pre[110<<1] , id[110<<1] ,vis[110<<1]; struct edge{ int u,v; double w; }e[110*110]; double calcu_dis(int x,int y) { return sqrt( (nod[x].x - nod[y].x) * (nod[x].x - nod[y].x) + (nod[x].y - nod[y].y) * (nod[x].y - nod[y].y)) ; } void makemap() { for(int i=0;i<m;i++){ scanf("%d%d",&e[i].u,&e[i].v) ; e[i].u--,e[i].v-- ; if(e[i].u == e[i].v) e[i].w=INF; else e[i].w=calcu_dis(e[i].u , e[i].v); } } double Direct_Mst(int root) { double ret = 0; while(1){ for(int i=0;i<n ;i++) in[i] = INF ; for(int i=0;i<m;i++){ int u = e[i].u ; int v = e[i].v ; if(e[i].w<in[v] && u!=v){ pre[v]= u; in[v]=e[i].w ; } } //判断能否遍历 for(int i=0;i<n;i++){ if(i!=root && in[i]==INF){ return -1; } } //找环 int cnt= 0; memset(id, -1 ,sizeof id) ; memset(vis , -1 , sizeof vis) ; in[root] = 0; for(int i=0;i<n;i++){ ret += in[i] ; int v= i; while(vis[v] != i && id[v]==-1 && v!=root){ vis[v] = i; v=pre[v] ; } if(v!=root && id[v] == -1){ for(int u = pre[v] ; u!=v ;u= pre[u]){ id[u] = cnt; } id[v] = cnt++; } } if(cnt == 0){ break; //没有环 } for(int i= 0;i<n ;i++){ if(id[i] == -1){ id[i] = cnt++; } } //有环则缩点重新标记 for(int i=0 ;i<m;i++){ int v=e[i].v; int u=e[i].u; e[i].u=id[u]; e[i].v=id[v]; if(e[i].u != e[i].v) e[i].w-=in[v] ; } n=cnt; root = id[root] ; } return ret ; } double solve() { makemap() ; double ret = Direct_Mst(0) ; return ret ; } int main() { while(~scanf("%d%d",&n,&m)){ for(int i=0;i<n;i++){ cin>>nod[i].x>>nod[i].y; } double ans=solve() ; if(ans == -1){ printf("poor snoopy\n") ; } else { printf("%.2f\n",ans) ; } } return 0; }
标签:
原文地址:http://www.cnblogs.com/Scale-the-heights/p/4711940.html