我对不起党,对不起国家,对不起人民HDU6201 补题(disj)

这个题目其实特别傻逼

但是因为数组开小了一直T

mmp!

其实就是建一个超级源点

对于每个点我们建一条有向边连接超级源点源点和这个点边权为a【k】

然后该怎么建图就怎么建图

跑一个最短路,求出超级源点到每个点的最短路,那么这个就是我从别的地方买,到这个点卖,买入价格+路费的最小值

然后emmmmm。。。。。再不会就别丢人了,退群吧

下面附上自己的1sAC代码,这个。。。。听说还有大丰收的做法

等晚上下课去学学

想想晚上还要被拉去演讲宪法什么的

更是无数个mmp在心头

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define ll long long
#define maxn 201000
#define MAXM 201000
#define MAXN 201000
#define sst 0
#define inf 0x3f3f3f3f

using namespace std;

struct Edge
{
    int v, w;
    int next;
}edge[MAXM*2];
int head[MAXN], d[MAXN], tot;
bool vis[MAXN];
void addedge(int u, int v, int w)
{
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

struct pii
{
    int a,b;
    pii(int x,int y)
    {a=x;b=y;}
};

bool operator > (pii a,pii b)
{
    return a.a>b.a;
}

void dijkstra(int s,int n)
{
    priority_queue<pii, vector<pii>, greater<pii> > Q;
    for (int k=0;k<=n;k++)
    {d[k]=0x3f3f3f3f;vis[k]=0;}
    d[s]=0;
    Q.push(pii(d[s], s));
    while(!Q.empty())
    {
        pii tmp = Q.top();
        Q.pop();
        int x = tmp.b;
        if(vis[x]) continue;
        vis[x] = true;
        for(int i = head[x]; i+1; i = edge[i].next)
        {
            if(d[edge[i].v] > d[x] + edge[i].w)
            {
                d[edge[i].v] = d[x] + edge[i].w;
                Q.push(pii(d[edge[i].v], edge[i].v));
            }
        }
    }
    return;
}

void init(int n)
{
    for (int k=0;k<=n;k++)
        head[k]=-1;
    tot=0;
}

int a[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        init(n);
        for (int k=1;k<=n;k++)
        {
            scanf("%d",&a[k]);
            addedge(sst,k,a[k]);
        }

        for (int k=1;k<=n-1;k++)
        {
            int st,en,val;
            scanf("%d %d %d",&st,&en,&val);
            addedge(st,en,val);
            addedge(en,st,val);
        }

        dijkstra(sst,n);

        int ans(0);
        for (int k=1;k<=n;k++)
            if (a[k]-d[k]>ans)
                ans=a[k]-d[k];
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值