SHADOWICENCXIX

导航

洛谷1342

dijkstra裸题啊。。。

其实楼下那些优化就一个堆优化即可的

算法复杂度(m+logm)

这里讲一个堆优化的注意(stl显然的对不对)

记得在遍历出边时打标记即可

还有记得加 long long

这样的话好像没啥好讲的了

上代码吧~

#include<stdio.h>
#include<queue>
using namespace std;
struct data//第一个邻接表存正向图
{
    int v;int next;int val;
}edge[1000010];int cnt;
int alist[1000010];
void add(int u,int v,int val)
{
    edge[++cnt].v=v;
    edge[cnt].val=val;
    edge[cnt].next=alist[u];
    alist[u]=cnt;
    return;
}
struct data2//第二个邻接表存反向图(回城的路径)
{
    int v;int next;int val;
}edge2[1000010];int cnt2;
int alist2[1000010];
void kid(int v,int u,int val)
{
    edge2[++cnt2].v=v;
    edge2[cnt2].val=val;
    edge2[cnt2].next=alist2[u];
    alist2[u]=cnt2;
    return;
}
struct node//一开始脑残想到了最小生成树,不要理我。。。直接int即可
{
    int d;int n;
    friend bool operator <(node a,node b)
    {
        return a.d>b.d;
    }
}d[1000010],now;
priority_queue <node> pq;//这里是int就好,不要学我
bool book[1000010];
int n;int m;
long long res;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int u;int v;int val;
        scanf("%d%d%d",&u,&v,&val);
        add(u,v,val);//正向建图
        kid(u,v,val);//反向建图
    }
    for(int i=1;i<=n;i++)//初始化
    {
        d[i].d=0x3f3f3f3f;
        d[i].n=i;
    }
    d[1].d=0;pq.push(d[1]);
    while(!pq.empty())//dijkstra膜板
    {
        now=pq.top();pq.pop();
        //printf("now %d\n",now.n);
        book[now.n]=true;
        int next=alist[now.n];
        while(next)
        {
            int v=edge[next].v;
            int val=edge[next].val;
            if(book[v]==false)
            {
                if(d[v].d>now.d+val)
                {
                    d[v].d=now.d+val;
                    pq.push(d[v]);
                    //printf("->d[%d]=%d\n",v,d[v].d);
                }
            }
            next=edge[next].next;
        }
    }
    for(int i=1;i<=n;i++)//处理出城车费
    {
        res+=d[i].d;
    }
    for(int i=1;i<=n;i++)//省个数组是个数组
    {
        d[i].d=0x3f3f3f3f;
        d[i].n=i;
    }
    d[1].d=0;pq.push(d[1]);
    while(!pq.empty())//再来一遍dijkstra膜板
    {
        now=pq.top();pq.pop();
        //printf("now %d\n",now.n);
        book[now.n]=false;
        int next=alist2[now.n];
        while(next)
        {
            int v=edge2[next].v;
            int val=edge2[next].val;
            if(book[v]==true)//数组能省就省
            {
                if(d[v].d>now.d+val)
                {
                    d[v].d=now.d+val;
                    pq.push(d[v]);
                    //printf("->d[%d]=%d\n",v,d[v].d);
                }
            }
            next=edge2[next].next;
        }
    }
    for(int i=1;i<=n;i++)//处理回城费用
    {
        res+=d[i].d;
    }
    printf("%lld",res);
    return 0;
}
QAQ我好像把手写邻接表当常识了。。
有stl链表这种操作?

posted on 2017-10-24 16:06  SHADOWICENCXIX  阅读(181)  评论(0编辑  收藏  举报