题目大意:给定n个点坐标,m条有向边,要求最小树形图。
题解:直接上模板,前面打的 vis[v]=i一直把i打成1,一直TLE。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<string> 6 #include<algorithm> 7 const double inf=200000000; 8 struct Point{ 9 int x,y; 10 }p[200005]; 11 struct Edge{ 12 double w; 13 int u,v; 14 }e[200005]; 15 int n,m; 16 double In[200005]; 17 int pre[200005],id[105],vis[105]; 18 double dis(int i,int j){ 19 return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)); 20 } 21 double zhuliu(){ 22 double ret=0; 23 int u,v,rt=0; 24 while (1){ 25 for (int i=0;i<n;i++) In[i]=inf; 26 for (int i=0;i<m;i++){ 27 u=e[i].u; 28 v=e[i].v; 29 if (e[i].w<In[v]&&u!=v){ 30 In[v]=e[i].w; 31 pre[v]=u; 32 } 33 } 34 for (int i=0;i<n;i++){ 35 if (i==rt) continue; 36 if (fabs(In[i]-inf)<1e-8) return -1; 37 } 38 int cnt=0; 39 memset(id,-1,sizeof id); 40 memset(vis,-1,sizeof vis); 41 In[rt]=0; 42 for (int i=0;i<n;i++){ 43 ret+=In[i]; 44 v=i; 45 while (v!=rt&&vis[v]!=i&&id[v]==-1){ 46 vis[v]=i; 47 v=pre[v]; 48 } 49 if (v!=rt&&id[v]==-1){ 50 for (u=pre[v];u!=v;u=pre[u]){ 51 id[u]=cnt; 52 } 53 id[v]=cnt++; 54 } 55 } 56 if (cnt==0) break; 57 for (int i=0;i<n;i++){ 58 if (id[i]==-1) id[i]=cnt++; 59 } 60 for (int i=0;i<m;i++){ 61 u=e[i].u; 62 v=e[i].v; 63 e[i].u=id[u]; 64 e[i].v=id[v]; 65 if (e[i].u!=e[i].v){ 66 e[i].w-=In[v]; 67 } 68 } 69 n=cnt; 70 rt=id[rt]; 71 } 72 return ret; 73 } 74 int main(){ 75 freopen("poj3164.in","r",stdin); 76 freopen("poj3164.out","w",stdout); 77 while (~scanf("%d%d",&n,&m)){ 78 for (int i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y); 79 for (int i=0;i<m;i++){ 80 scanf("%d%d",&e[i].u,&e[i].v); 81 e[i].u--;e[i].v--; 82 if (e[i].u==e[i].v) e[i].w=inf; 83 else 84 e[i].w=dis(e[i].u,e[i].v); 85 } 86 double t=zhuliu(); 87 if (t<0.0) printf("poor snoopy "); 88 else printf("%.2f ",t); 89 } 90 }