hdu 1535 Invitation Cards(有向图的来回最短路,要反向建图)

题目:

链接:点击打开链接

题意:

给一个图,求1到各点和各点到1最短路。

思路:

先spfa,然后反向建图,在spfa就行了。

代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define INF 100000000

const int N = 1000010;

struct node{
    int u,v,w;
}edge[N];

int dis[N],vis[N];
int first[N],next[N];
int p,m;

void spfa1(int u)
{
    for(int i=0; i<=p; i++)
    {
        dis[i] = INF;
    }
    dis[u] = 0;
    memset(vis,0,sizeof(vis));
    queue<int> q;
    q.push(u);
    while(!q.empty())
    {
        u = q.front();
        q.pop();
        vis[u] = 0;
        for(int k=first[u]; k!=-1; k=next[k])
        {
            int v = edge[k].v;
            if(dis[v] > dis[u] + edge[k].w)
            {
                dis[v] = dis[u] + edge[k].w;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

void spfa2(int u)
{
    for(int i=0; i<=p; i++)
    {
        dis[i] = INF;
    }
    dis[u] = 0;
    memset(vis,0,sizeof(vis));
    queue<int> q;
    q.push(u);
    while(!q.empty())
    {
        u = q.front();
        q.pop();
        vis[u] = 0;
        for(int k=first[u]; k!=-1; k=next[k])
        {
            int v = edge[k].u;
            if(dis[v] > dis[u] + edge[k].w)
            {
                dis[v] = dis[u] + edge[k].w;
                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

void buildGraph()
{
    memset(next,-1,sizeof(next));
    memset(first,-1,sizeof(first));
    for(int i=0; i<m; i++)
    {
        int v = edge[i].v;
        next[i] = first[v];
        first[v] = i;
    }
}

int main()
{
    //freopen("input.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d%d",&p,&m);
        memset(first,-1,sizeof(first));
        memset(next,-1,sizeof(next));
        for(int i=0; i<m; i++)
        {
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
            next[i] = first[edge[i].u];
            first[edge[i].u] = i;
        }
        spfa1(1);
        int result = 0;
        for(int i=2; i<=p; i++)
        {
            result += dis[i];
        }
        buildGraph();
        spfa2(1);
        for(int i=2; i<=p; i++)
        {
            result += dis[i];
        }
        printf("%d\n",result);
    }
    return 0;
}

-----------------------------------------------------------------------

收获:

->学习到了SPFA算法:

->思想:

->模板:

void add(int i,int j,int w)
{
    e[t].from=i;
    e[t].to=j;
    e[t].w=w;
    e[t].next=head[i];
    head[i]=t++;
}
void spfa(int s)
{
    queue <int> q;
    for(int i=1;i<=n;i++)
    dist[i]=inf;
    memset(vis,false,sizeof(vis));
    q.push(s);
    dist[s]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            if(dist[v]>dist[u]+e[i].w)
            {
                dist[v]=dist[u]+e[i].w;
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
}

-----------------------------------------------------------

战斗,从不退缩;奋斗,永不停歇~~~~~~~~~~

hdu 1535 Invitation Cards(有向图的来回最短路,要反向建图)

时间: 2024-10-08 11:31:19

hdu 1535 Invitation Cards(有向图的来回最短路,要反向建图)的相关文章

HDU 1535 Invitation Cards (POJ 1511)

两次SPFA.求 来 和 回 的最短路之和. 用Dijkstra+邻接矩阵确实好写+方便交换,但是这个有1000000个点,矩阵开不了. d1[]为 1~N 的最短路. 将所有边的 邻点 交换. d2[] 为 1~N 的最短路. 所有相加为 所要答案. 忧伤的是用SPFA  "HDU 1535"  AC了,但是POJ 一样的题 "POJ 1511" 就WA了. 然后强迫症犯了,不停的去测试. 题意中找到一句关键话 :Prices are positive integ

HDU 1535 Invitation Cards (最短路,附SLF优化SPFA)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=1535 题意: 有向图,求点1到点2-n的最短距离之和以及点2-n到点1的最短距离之和 方法: 1.跑1为原点的最短路 2.反向建图(把有向图的边反向,(u,v,w)变成(v,u,w)),跑1为原点的最短路 3.将两者距离之和加和即可(注意用 long long ,int会溢出) 1 void input() 2 { 3 scanf("%d%d", &n, &m); 4 g1.

HDU - 1535 Invitation Cards 前向星SPFA

Invitation Cards In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards wit

hdu 1535 Invitation Cards 大年初一首A 一次正向SPFA+一次逆向SPFA

Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2311    Accepted Submission(s): 1125 Problem Description In the age of television, not many people attend theater performances.

hdu 1535 Invitation Cards(SPFA)

Invitation Cards Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total Submission(s) : 28   Accepted Submission(s) : 14 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description In the age of telev

hdu 1535 Invitation Cards

#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int inf=1<<24; const int N=1000000+5; struct node { int to,w; node* next; }; node* edge[N]; node* reedge[N]; int n,m,x,dist[N

HDU ACM 1535 Invitation Cards单点到多源最短路-&gt;SPFA算法

题意:有一个起始站点,从这里送n个学生去其余的n-1个站点邀请人们去CSS,然后再返回CSS,使得总的花费最小.注意每次只能送一个,返回时每次也只能送一个,而且每条路是单向的. 分析:这相当于一个有向图,我们只需两次调用SPFA算法即可,第一次求出初始站点(在这里是1)到其它所有站点的最小花费,然后相加:第二次将图反向建立,即所有的边反向,再求出初始站点(这里是1)到其它站点的最小费用,之后相加,第二步的图反向后按照第一次的求法就相当于从其它所有点到初始点的最小距离,因为算法只能求单点到多点而不

HDU1535Invitation Cards(有向图,正向建图和反向建图各spfa一次)

Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2374    Accepted Submission(s): 1151 Problem Description In the age of television, not many people attend theater performances.

HDU 3639 Hawk-and-Chicken(强连通缩点+反向建图)

http://acm.hdu.edu.cn/showproblem.php?pid=3639 题意: 有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两票),输出最多能获得的票数是多少张和获得最多票数的人是谁? 思路: 先强连通缩点反向建图,在计算强连通的时候,需要保存每个连通分支的结点个数. 为什么要反向建图呢?因为要寻找票数最多的,那么肯定是入度为0的点,然后dfs计算它的子节点的