1050: [HAOI2006]旅行comf

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1050

将边从小到大排序,枚举边权最小的边k,从第k条边开始一条一条边插入,用并查集维护,直到s、t连通。

#include <iostream>
#include 
<cstring>
#include 
<cstdlib>
#include 
<cstdio>
#include 
<algorithm>
using namespace std;
const int MaxN=501;
const int MaxM=5001;
const double oo=100000001;

struct line
{
    
int x,y;
    
int v;
}
;

int n,m,s,t,ansa,ansb;
double ans=oo;
int father[MaxN];
line a[MaxM];

void init()
{
    cin
>>n>>m;
    
for (int i=0;i<m;i++)
    
{
        cin
>>a[i].x>>a[i].y>>a[i].v;
    }

    cin
>>s>>t;
}


bool cmp(line a,line b)
{
    
return a.v<b.v;
}


int find(int x)
{
    
if (father[x]==x)
    
{
        
return x;
    }

    
return father[x]=find(father[x]);
}


void work(int st)
{
    
for (int i=1;i<=n;i++)
    
{
        father[i]
=i;
    }

    
for (int i=st;i<m;i++)
    
{
        
int x=find(a[i].x),y=find(a[i].y);
        
if (x!=y)
        
{
            father[x]
=y;
        }

        
if (find(s)==find(t))
        
{
            
if ((double)a[i].v/(double)a[st].v<ans)
            
{
                ans
=(double)a[i].v/(double)a[st].v;
                ansa
=a[i].v;
                ansb
=a[st].v;
            }

            
return;
        }

    }

}


int gcd(int a,int b)
{
    
if (b==0)
    
{
        
return a;
    }

    
return gcd(b,a%b);
}


int main()
{
    init();
    sort(a,a
+m,cmp);
    
for (int i=0;i<m;i++)
    
{
        work(i);
    }

    
if (ans==oo)
    
{
        cout
<<"IMPOSSIBLE"<<endl;
    }

    
else
    
{
        
int k=gcd(ansa,ansb);
        cout
<<ansa/k;
        
if (ansb/k!=1)
        
{
            cout
<<'/'<<ansb/k<<endl;
        }

        
else
        
{
            cout
<<endl;
        }

    }

    
return 0;
}


 

posted on 2013-02-14 21:18 Kiro 阅读(150) 评论(0)  编辑 收藏 引用 所属分类: 衡八oj