Legacy CodeForces - 787D

http://codeforces.com/problemset/problem/787/D

线段树建图纯模板题

#include 
using namespace std;
#define ll long long
#define N 0x3f3f3f3f3f3f3f3f

struct node1
{
    int v;
    ll w;
    int next;
};

struct node2
{
    bool friend operator < (node2 n1,node2 n2)
    {
        return n1.val>n2.val;
    }
    int id;
    ll val;
};

node1 edge[4000010];
priority_queue  que;
ll dis[1000010];
int first[1000010],mp[100010],book[1000010];
int n,q,s,num;

void addedge(int u,int v,ll w)
{
    //printf("*%d %d %lld*\n",u,v,w);
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=first[u];
    first[u]=num++;
}

void build(int l,int r,int cur)
{
    int m;
    if(l==r)
    {
        mp[l]=800000+l;
        addedge(cur,800000+l,0);
        addedge(800000+l,400000+cur,0);
        return;
    }
    m=(l+r)/2;
    addedge(cur,2*cur,0);
    addedge(cur,2*cur+1,0);
    addedge(400000+2*cur,400000+cur,0);
    addedge(400000+2*cur+1,400000+cur,0);
    build(l,m,2*cur);
    build(m+1,r,2*cur+1);
}

void update(int op,int pl,int pr,int tar,ll val,int l,int r,int cur)
{
    int m;
    if(pl<=l&&r<=pr)
    {
        if(op==2) addedge(tar,cur,val);
        else addedge(400000+cur,tar,val);
        return;
    }
    m=(l+r)/2;
    if(pl<=m) update(op,pl,pr,tar,val,l,m,2*cur);
    if(pr>m) update(op,pl,pr,tar,val,m+1,r,2*cur+1);
}

void dijkstra()
{
    node2 cur,tmp;
    ll w;
    int i,u,v;
    while(!que.empty()) que.pop();
    memset(dis,0x3f,sizeof(dis));
    memset(book,0,sizeof(book));
    tmp.id=mp[s],tmp.val=0;
    que.push(tmp);
    dis[mp[s]]=0;
    while(!que.empty())
    {
        cur=que.top();
        que.pop();
        u=cur.id;
        if(book[u]) continue;
        //printf("***%d***\n",u);
        book[u]=1;
        for(i=first[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].v,w=edge[i].w;
            if(!book[v]&&dis[v]>dis[u]+w)
            {
                //printf("*%d %lld*\n",v,w);
                dis[v]=dis[u]+w;
                tmp.id=v,tmp.val=dis[v];
                que.push(tmp);
            }
        }
    }
    for(i=1;i<=n;i++)
    {
        if(dis[mp[i]]==N) printf("-1 ");
        else printf("%lld ",dis[mp[i]]);
    }
    printf("\n");
}

int main()
{
    ll w;
    int op,u,v,l,r;
    scanf("%d%d%d",&n,&q,&s);
    memset(first,-1,sizeof(first));
    num=0;
    build(1,n,1);
    while(q--)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d%lld",&u,&v,&w);
            addedge(mp[u],mp[v],w);
        }
        else
        {
            scanf("%d%d%d%lld",&u,&l,&r,&w);
            update(op,l,r,mp[u],w,1,n,1);
        }
    }
    dijkstra();
    return 0;
}

 

你可能感兴趣的:(线段树/树状数组/RMQ,最短路)