asd的甩锅计划

asd的甩锅计划

时间限制: 1 Sec  内存限制: 128 MB
提交: 177  解决: 19
[提交][状态]

题目描述

大家对hdu上面的畅通工程系列一定很熟悉了吧。比如如下一段,就是畅通工程里面其中一个题的叙述。
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
大 家觉得这种情况一定很简单而且生活中遇不到吧。然而你错了!NBUT的书记yh就遇到了这么个头疼事:asd下达命令让村长去把村里的路修的高端大气上档 次,简单说就是重新建路,可是村长又甩手把这事给了yh书记。然而现在一个大问题是:经费不够用!因此yh书记觉得不可能每家每户都有一条道路通往村里任 意一家,只要能走到就行了(不管是直接到达还是先经过别人家这样的间接到达)。
NBUT 是个有名的“坑”地方,不是地方坑,而是地方有坑,这样的话在那些有坑的地方修路和在平地上修路的价钱当然不一样啦。更坑的是,村长已经划好一些可能要修 的路线了,你只能在这些线路上面选一些来修。比如说,尽管村长要修的路连着张三丰和李四收,这条路会经过一些坑,但是你决定修这条路的话不能绕过它,只能 去填平,经费当然不一样啦,当然你也可以选择不去修这条路,只要能让村子里每户人家能相互到达就可以了。
现 在yh书记已经知道村里有n户人家了,并且拿到村长给他的平面设计图,上面标明哪些路要修多长,和修这条路的费用,现在书记来请教你,完成镇里的任务最少 需要修多长的路,和最少要花多少钱。书记是个爱民的人,希望村民能省力就省力,所以多花一些钱修更短的路是无所谓的,但是能完成这个任务当然还是能省钱就 省钱。另外村长图里的起点终点相同的两条路是认为不一样的,可能按路线1建路比路线2减更短更省钱,谁知道呢~所以若是按照村长的图不能完成村里的任务, 那么就输出“村长你家铺子烧啦”。

输入

        每行两个整数n(1 <= n <= 1000),m (1 <= m <= 2e6+7),分别表示村里有多少户人家,和村长给的图里面的路线。
接下来m行,每行四个整数 a, b, c, d(1 <= a, b <= n, 1 <= c <= 1000, 1 <= d <= 1e9+7),分别表示农民a家到b家建一条路的话,长度是c,花费是d。

输出

       对于每组数据,如果能满足建路要求,那么每行输出两个整数 length, cost,分别表示一共要修路的长度,和修路的花费,具体如题意描述。否则输出“村长你家铺子烧啦”。

样例输入

2 1
1 2 3 4

样例输出

3 4

最小生成树,在保证路最短的情况下,找话费最小的~Kurscal,prim不知道为啥一直runtime error
#include<iostream>
#include<algorithm>
#include<cstdio>
 
using namespace std;
 
#define N 1100
#define INF 0xfffffff
 
long long len, cost, f[N], n, m;
 
struct node
{
    long long x, y, l, c;
}P[N*N];  // 如果 你写P[N]运行错误?用N*N才行~因为最多可以有n*n条边~
 
bool cmp(node a, node b)
{
    if(a.l != b.l)
        return a.l < b.l;
    return a.c < b.c;
}
 
int found(int x)
{
    if(f[x] != x)
        f[x] = found(f[x]);
    return f[x];
}
 
void kurscal()
{
    for(int i = 0; i < m; i++)
    {
        int nx = found(P[i].x), ny = found(P[i].y);
 
        if(nx != ny)
        {
            f[nx] = ny;
            len += P[i].l;
            cost += P[i].c;
        }
    }
}
 
int main()
{
    //long long a, b, l, c;
 
    while(cin >> n >> m)
    {
        len = cost = 0;
 
        for(int i = 1; i <= n; i++)
            f[i] = i;
 
        for(int i = 0; i < m; i++)
            cin >> P[i].x >> P[i].y >> P[i].l >> P[i].c;
 
        sort(P, P+m, cmp);
 
        kurscal();
 
        int cou = 0;
 
        for(int i = 1; i <= n; i++)
        {
            if(f[i] == i)
                cou++;
        }
        if(cou > 1)
            printf("村长你家铺子烧啦\n");
        else
            cout << len << ' ' << cost << endl;
    }
    return 0;
}

 prim

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
#define maxn 1010
typedef long long LL;
const int INF = 1000000500;
bool vis[maxn];
int m, n, dist[maxn];
LL cost[maxn];
 
struct node
{
    int L, V;
}maps[maxn][maxn];
 
void init()
{
    memset(vis, false, sizeof(vis) );
    memset(cost, 0, sizeof(cost));
    for(int i=1; i<=n ;i++)
    {
        dist[i] = INF;
        for(int j=1; j<=n; j++)
            maps[i][j].L = maps[i][j].V = INF;
        maps[i][i].L = maps[i][i].V = 0;
    }
 
}
 
void Prime()
{
    dist[1] = 0;
    for(int i=0; i<n; i++)
    {
        int Index = -1, Min = INF, MinCost = INF;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j] && (Min > dist[j] || (Min == dist[j] && MinCost > cost[j])) && dist[j] != INF )
                Min = dist[j], Index = j, MinCost = cost[j];
        }
 
        if(Index == -1)
        {
            puts("村长你家铺子烧啦");
            return ;
        }
 
        vis[Index] = true;
 
        for(int j=1; j<=n; j++)
        {
            if(!vis[j] && (dist[j] > maps[Index][j].L || (dist[j] == maps[Index][j].L && cost[j]>maps[Index][j].V) ) )
            {
                dist[j] = maps[Index][j].L;
                cost[j] = maps[Index][j].V;
            }
 
        }
    }
    LL Len = 0, Cost = 0;
 
    for(int i=1; i<=n; i++)
    {
        Len += dist[i];
        Cost += cost[i];
    }
    printf("%lld %lld\n", Len, Cost);
}
 
int main()
{
    while(scanf("%d %d",&n, &m) != EOF)
    {
        init();
        while(m --)
        {
            int a, b, c, d;
            scanf("%d %d %d %d",&a, &b, &c, &d);
 
            if(maps[a][b].L > c || (maps[a][b].L == c && maps[a][b].V > d) )
                maps[a][b].L = c, maps[a][b].V = d;
            maps[b][a] = maps[a][b];
        }
        Prime();
    }
    return 0;
}

非得结构体存储才对吗

转载于:https://www.cnblogs.com/Tinamei/p/4689827.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值