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;
}