HDU3371&&POJ2485

额,两道简单的最小生成树,POJ那题本来用PRIM写更好- -不过我转成Kluskal去练手了,顺便说一下这两题最坑的地方是用G++会超时,不管你是cin cout还是 printf scanf,然后换成C++才涉险过关,查了一下网上说可能是在sort里面卡了时间,表示好厉害的样纸完全不懂- -。。。刷的最小生成树也基本都是很简单的题目o(╯□╰)o增加熟悉程度而已。。。还得继续努力。唯一的赶脚就是HUST那次月赛的签到题现在可以瞬秒了吧- -|||

Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7902    Accepted Submission(s): 2247


Problem Description
In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don’t want to take too much money.  
 

Input
The first line contains the number of test cases.
Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected cities.
To make it easy, the cities are signed from 1 to n.
Then follow


m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.
Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.
 

Output
For each case, output the least money you need to take, if it’s impossible, just output -1.
 

Sample Input
  
  
1 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 1 3 3 4 5 6
 

Sample Output
  
  
1
 
HDU这题是告诉你有M条边,但是有K行 每行有T的城市,表示他们已经与T个城市中的第一个城市联通了,所以得把它们默认进集合中,当然加进去得默认权值是0,否则会

影响结果,然后在已经加完的剩下的里面继续用Kluskal进行加边,求出最小权值即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;

struct node{

int s;
int e;
int w;

}edge[35000];

int n,m,k;
int sum;
int num;
int pre[505];

int c;
void init()
{
    int i;
    for(i=1;i<=n;i++)
    {
        pre[i]=i;

    }
}

int find(int x)
{
    if(x==pre[x])
        return pre[x];
    pre[x]=find(pre[x]);
    return pre[x];
}
void join(int x,int y,int w)
{
    int fx=find(x);
    int fy=find(y);
   if(fx!=fy)
   {
       pre[fx]=fy;
       sum+=w;
       num--;
   }

}
bool cmp(node a,node b)
{
    return a.w<b.w;
}
int main()
{
    scanf("%d",&c);
    while(c--)
    {   scanf("%d%d%d",&n,&m,&k);
        init();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].w);
        }
        sum=0;
        num=n;
        int t;
        int a,b;
        for(int i=1;i<=k;i++)
        {
           scanf("%d%d",&t,&a);


            for(int j=1;j<t;j++)
            {
               scanf("%d",&b);
                join(a,b,0);
            }


        }
        if(num!=1)
        {
            sort(edge,edge+m+1,cmp);//尼玛后来用C++交还WA了是因为最近都是从1-N的闭区间了所以应该是edge+m+1才对= =|||
            for(int i=1;i<=m;i++)
            {
                join(edge[i].s,edge[i].e,edge[i].w);
            }
        }
        if(num==1)
           printf("%d\n",sum);
        else
            printf("-1\n");
    }



    return 0;
}





Highways
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 19849 Accepted: 9204

Description

The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're planning to build some highways so that it will be possible to drive between any pair of towns without leaving the highway system.

Flatopian towns are numbered from 1 to N. Each highway connects exactly two towns. All highways follow straight lines. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.

The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.

Input

The first line of input is an integer T, which tells how many test cases followed.
The first line of each case is an integer N (3 <= N <= 500), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 65536]) between village i and village j. There is an empty line after each test case.

Output

For each test case, you should output a line contains an integer, which is the length of the longest road to be built such that all the villages are connected, and this value is minimum.

Sample Input

1

3
0 990 692
990 0 179
692 179 0

Sample Output

692

Hint

Huge input,scanf is recommended.
这个给你邻接矩阵只不过手贱把它转成了KLUSKAL来做罢了- -。因为写并查集现在写的顺手一点囧,这题是在生成最小生成树后,求该棵树里的某条边权值最大者。

所以每次并查集发现没环加入进去的时候记得把权值扔进另一个新开的数组,然后放完后排序一下输出最后的就是答案了~

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;

struct node{
int x;
int y;
int w;

}edge[250000];
int pre[505];
int t,n;
int map[505][505];
int a[250005];
int find(int x)
{
    if(x==pre[x])
        return pre[x];
    pre[x]=find(pre[x]);
    return pre[x];
}

void init()
{
    int i;
    for(i=1;i<=n;i++)
    {
        pre[i]=i;
    }
}

void join(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
        pre[fx]=fy;
}
bool cmp(node a,node b)
{
    return a.w<b.w;
}

int main()
{
    cin>>t;

    while(t--)
    {
        cin>>n;
        int k=0;
        int m=0;
        int count=0;
        init();
        int i,j;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                cin>>map[i][j];
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=i+1;j<=n;j++)
            {
              edge[k].x=i;
              edge[k].y=j;
              edge[k].w=map[i][j];
              k++;
            }
        }
        sort(edge,edge+k,cmp);
        for(i=0;i<k;i++)
        {
            if(find(edge[i].x)!=find(edge[i].y))
            {
                join(edge[i].x,edge[i].y);
                a[m++]=edge[i].w;
                count++;
            }
            if(count==n-1)
            {
                break;
            }
        }
        sort(a,a+m);
        cout<<a[m-1]<<endl;
    }

    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值