BZOJ2725 [Violet 6]故乡的梦

来源:互联网 发布:招聘网络总监 编辑:程序博客网 时间:2024/05/01 01:03

想日这道题都得有一年了……今天发现yh都把这题日了,我才终于来日他

这题题解网上都烂大街了,我也懒得写……不过这题其实不需要线段树的

先任意搞一条S到T的最短路,然后对于不在最短路上的一条边,x->y,假设我们要强制经过这条边的话,最优情况一定是S走最短路到x,再x->y,再y走最短路到T

那么S走最短路到x一定是先走一段S到T的最短路,然后离开最短路,y走到T一定是先走一段别的路,然后进入S到T的最短路

那么这个路径就可以用来更新最短路上一段区间的答案

那么我们用一个multiset扫一遍就行了,不过这么搞常数好像比线段树大,我不加读入优化就TLE了-_-

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<bitset>#include<set>#include<map>#include<vector>#include<stack>#include<queue>using namespace std;#define MAXN 200010#define MAXM 1010#define INF 1000000000#define MOD 1000000007#define eps 1e-8#define ll long longchar xch,xB[1<<15],*xS=xB,*xTT=xB;#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)inline int read(){int x=0,f=1;char ch=getc();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}return x*f;}struct data{int x;ll v;data(){}data(int _x,ll _v){x=_x;v=_v;}friend bool operator <(data x,data y){return x.v>y.v;}};struct vec{int to;int fro;int v;};vec mp[MAXN*2];int tai[MAXN],cnt;priority_queue<data>q;int n,m,Q;map<pair<int,int>,ll>h;map<pair<int,int>,bool>arr;bool vis[MAXN];int rds[MAXN],rdt[MAXN];ll diss[MAXN],dist[MAXN];bool ar[MAXN];bool fds[MAXN],fdt[MAXN];vector<ll>irs[MAXN],drs[MAXN];multiset<ll>s;int S,T;int v1[MAXN],v2[MAXN],v[MAXN];int fvs[MAXN],fvt[MAXN];int dep[MAXN];inline void be(int x,int y,int z){mp[++cnt].to=y;mp[cnt].fro=tai[x];tai[x]=cnt;mp[cnt].v=z;}inline void bde(int x,int y,int z){be(x,y,z);be(y,x,z);}int find(int x,int *rd,bool *fd,int *fv){if(fd[x]){return fv[x];}fd[x]=1;if(ar[x]){return fv[x]=x;}return fv[x]=find(rd[x],rd,fd,fv);}void dijkstra(int s,ll *dis,int *rd){int i,x,y;memset(vis,0,sizeof(vis));memset(dis,0x3f,sizeof(dis));for(i=1;i<=n;i++){vis[i]=0;dis[i]=1000000000000000000ll;}q.push(data(s,dis[s]=0));while(!q.empty()){x=q.top().x;q.pop();if(vis[x]){continue ;}vis[x]=1;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;if(dis[y]>dis[x]+mp[i].v){rd[y]=x;q.push(data(y,dis[y]=dis[x]+mp[i].v));}}}}int main(){int i,x,y,z;n=read();m=read();for(i=1;i<=m;i++){v1[i]=read();v2[i]=read();v[i]=read();bde(v1[i],v2[i],v[i]);}S=read();T=read();dijkstra(S,diss,rds);dijkstra(T,dist,rdt);ar[0]=1;if(vis[S]){x=T;dep[T]=1;while(x!=S){ar[x]=1;arr[make_pair(x,rds[x])]=1;arr[make_pair(rds[x],x)]=1;dep[rds[x]]=dep[x]+1;x=rds[x];}ar[S]=1;for(i=1;i<=m;i++){if(arr[make_pair(v1[i],v2[i])]){continue ;}x=find(v1[i],rds,fds,fvs);y=find(v2[i],rdt,fdt,fvt);if(x&&y&&dep[y]<dep[x]){irs[y].push_back(diss[v1[i]]+dist[v2[i]]+v[i]);drs[x].push_back(diss[v1[i]]+dist[v2[i]]+v[i]);}x=find(v2[i],rds,fds,fvs);y=find(v1[i],rdt,fdt,fvt);if(x&&y&&dep[y]<dep[x]){irs[y].push_back(diss[v2[i]]+dist[v1[i]]+v[i]);drs[x].push_back(diss[v2[i]]+dist[v1[i]]+v[i]);}}for(x=T;x!=S;x=rds[x]){for(i=0;i<irs[x].size();i++){s.insert(irs[x][i]);}for(i=0;i<drs[x].size();i++){s.erase(s.find(drs[x][i]));}if(s.size()){h[make_pair(x,rds[x])]=*s.begin();h[make_pair(rds[x],x)]=*s.begin();}else{h[make_pair(x,rds[x])]=-1;h[make_pair(rds[x],x)]=-1;}}}Q=read();while(Q--){x=read();y=read();if(!vis[S]){printf("Infinity\n");continue ;}if(!arr[make_pair(x,y)]){printf("%lld\n",diss[T]);}else if(h[make_pair(x,y)]==-1){printf("Infinity\n");}else{printf("%lld\n",h[make_pair(x,y)]);}}return 0;}/*6 7 1 2 1 2 3 1 3 4 24 5 15 6 1 1 3 3 4 6 3 1 6 4 1 2 1 3 4 3 6 5 */


0 0
原创粉丝点击