hdu6201(拆点加最长路)

来源:互联网 发布:设置截图路径 mac 编辑:程序博客网 时间:2024/06/06 01:36

题目

做题时候只想到最短路,疯狂超时,然后。。。。
还有最长路?还是spfa。。。菜哭了。

建立一个源点和汇点,然后源点到每个点的权值是点权,然后每个点到汇点的权值是负的点权,每个点之间的权值是负的边权,跑一个最长路。

#include<bits/stdc++.h>using namespace std;int used[100005], head[100005], low[100005],a[100005],k=0,cnt[100005],n;struct Edge{    int to, w, next;} edge[1000005];void add(int a,int b,int w){    edge[k].to = b;    edge[k].w = w;    edge[k].next = head[a];    head[a] = k++;}void SPFA(int start){    queue<int> a;    memset(cnt,0,sizeof cnt);    used[start] = 1;    low[start] = 0;    a.push(start);    while (!a.empty())    {        int top = a.front();        a.pop();        used[top]=0;        for (int i = head[top]; i != -1; i = edge[i].next)        {            if (low[edge[i].to] < low[top] + edge[i].w)            {                low[edge[i].to] = low[top] + edge[i].w;                if (!used[edge[i].to])                {                    cnt[edge[i].to]++;                    used[edge[i].to] = 1;                    a.push(edge[i].to);                    if(cnt[edge[i].to]>n)                        return ;                }            }        }    }    return;}int main(){    int t;    scanf("%d",&t);    while (t--)    {        memset(used, 0, sizeof(used));        memset(head, -1, sizeof(head));        memset(low, 0, sizeof(low));        memset(a,0,sizeof a);        k=0;        scanf("%d",&n);        for(int i = 1 ;i <= n; i++)        {            scanf("%d",&a[i]);            add(0,i,a[i]);            add(i,n+1,-a[i]);        }        int a,b,w;        for(int i = 1 ;i <= n-1; i++)        {            scanf("%d %d %d",&a,&b,&w);            add(a,b,-w);            add(b,a,-w);        }        SPFA(0);        printf("%d\n",low[n+1]);    }}
原创粉丝点击