bzoj2725: [Violet 6]故乡的梦&&bzoj4400: tjoi2012 桥

来源:互联网 发布:零基础java用什么书 编辑:程序博客网 时间:2024/04/30 12:17

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2725

http://www.lydsy.com/JudgeOnline/problem.php?id=4400

思路:首先随便找到一条最短路

如果删除一条边(x,y),那么最短路就会绕开x和y走一段

即S->最短路上的一个点->不在最短路的某些边->最短路上的一个点->T

对于每个不在选定的最短路上的点,求出fs[x]表示S到x的最短路在哪个点脱离选定的最短路

ft[y]表示从y到T的最短路在哪个点进入选定的最短路

即S->fs[x]->x->y->ft[y]->T

那么对于一条不在最短路的边,它就有可能在删去fs[x]与ft[y]之间的最短路边时发挥作用

记录ans[i]表示最短路上第i条边删去后的答案

处理每条不在最短路上的边,就在线段树上对fs[x]到ft[y]这段区间覆盖取min即可。

4400类似,因为找fs和ft时没有判是否已经找过,直接被卡T,上pbds都没用.


#include<queue>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define ls (p<<1)#define rs ((p<<1)|1)#define mid ((l+r)>>1)#define mp(a,b) make_pair(a,b)#define dist first#define id second#define abs(a) (a>0?a:-(a))typedef long long ll;const int maxn=200010,maxm=400010;using namespace std;typedef pair<ll,int> PI;int pre[maxm],now[maxn],son[maxm],tot,n,m,Q,S,T,pos[maxn],len,idx[maxn],fs[maxn],ft[maxn];ll ds[maxn],dt[maxn],inf,ans[maxn],val[maxm];struct Edge{int u,v;ll w;}E[maxm];struct Tsegment{ll cov[maxn<<2],v[maxn<<2];void cover(int p,ll va){v[p]=min(v[p],va),cov[p]=min(cov[p],va);}void down(int p){if (cov[p]!=inf) cover(ls,cov[p]),cover(rs,cov[p]),cov[p]=inf;}void build(int p,int l,int r){cov[p]=v[p]=inf;if (l==r) return;build(ls,l,mid),build(rs,mid+1,r);}void modify(int p,int l,int r,int a,int b,ll va){if (l==a&&r==b){cover(p,va);return;}down(p);if (b<=mid) modify(ls,l,mid,a,b,va);else if (a>mid) modify(rs,mid+1,r,a,b,va);else modify(ls,l,mid,a,mid,va),modify(rs,mid+1,r,mid+1,b,va);}void query(int p,int l,int r){if (l==r){ans[l]=v[p];return;}down(p),query(ls,l,mid),query(rs,mid+1,r);}void modify(int l,int r,ll va){modify(1,1,len-1,l,r,va);}void query(){query(1,1,len-1);}}Tree;priority_queue<PI,vector<PI>,greater<PI> > q;int que[maxm+10],head,tail;bool vis[maxn];bool inpath(int x,int y){return pos[x]&&pos[y]&&abs(pos[x]-pos[y])==1;}void add(int a,int b,ll c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}void dijkstra(int s,ll dis[]){q.push(mp(dis[s]=0,s)),inf=dis[0];while (!q.empty()){PI x=q.top();q.pop();for (int y=now[x.id];y;y=pre[y])if (x.dist+val[y]<dis[son[y]])q.push(mp(dis[son[y]]=x.dist+val[y],son[y]));}}void getway(){for (int x=S,last=-1;;){pos[x]=++len,idx[len]=x;if (x==T) break;for (int y=now[x];y;y=pre[y])if (son[y]!=last&&ds[x]+val[y]+dt[son[y]]==ds[T]){last=x,x=son[y];break;}}}void getfir(int s,ll dis[],int fir[]){que[tail=1]=s,fir[s]=s,head=0;while (head!=tail){int x=que[++head>maxm?1:head];for (int y=now[x];y;y=pre[y])if (!pos[son[y]]&&!fir[son[y]]&&dis[son[y]]==dis[x]+val[y])//要判!fir[son[y]]que[++tail>maxm?1:tail]=son[y],fir[son[y]]=s;}}int main(){scanf("%d%d",&n,&m);ll z;for (int i=1,x,y;i<=m;i++) scanf("%d%d%lld",&x,&y,&z),E[i]=(Edge){x,y,z},add(x,y,z),add(y,x,z);scanf("%d%d%d",&S,&T,&Q);memset(ds,63,sizeof(ds)),dijkstra(S,ds);if (ds[T]==inf){for (int i=1;i<=Q;i++) puts("Infinity");return 0;}memset(dt,63,sizeof(dt)),dijkstra(T,dt),getway();for (int i=1;i<=len;i++) getfir(idx[i],ds,fs);for (int i=len;i;i--) getfir(idx[i],dt,ft);Tree.build(1,1,len-1);for (int i=1;i<=m;i++){int u=E[i].u,v=E[i].v;ll w=E[i].w;if (!fs[u]||!fs[v]||inpath(u,v)) continue;if (pos[fs[u]]<pos[ft[v]]) Tree.modify(pos[fs[u]],pos[ft[v]]-1,ds[u]+dt[v]+w);if (pos[fs[v]]<pos[ft[u]]) Tree.modify(pos[fs[v]],pos[ft[u]]-1,ds[v]+dt[u]+w);}Tree.query();for (int i=1,x,y;i<=Q;i++){scanf("%d%d",&x,&y);if (!inpath(x,y)) printf("%lld\n",ds[T]);else{if (pos[x]>pos[y]) swap(x,y);if (ans[pos[x]]>=inf) puts("Infinity");else printf("%lld\n",ans[pos[x]]);}}return 0;}


#include<ctime>#include<queue>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<ext/pb_ds/priority_queue.hpp>#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)#define swap(a,b) std::swap(a,b)#define ls (p<<1)#define rs ((p<<1)|1)#define mid ((l+r)>>1)#define mp(a,b) std::make_pair(a,b)#define dist first#define id second#define abs(a) (a>0?a:-(a))//typedef long long int;const int maxn=200010,maxm=400010;//using namespace std;typedef std::pair<int,int> PI;int pre[maxm],now[maxn],son[maxm],tot=1,n,m,Q,S,T,pos[maxn],len,idx[maxn],fs[maxn],ft[maxn],cnt;int ds[maxn],dt[maxn],inf,ans[maxn],val[maxm],res,ord[maxm];struct Edge{int u,v;int w;}E[maxm];struct Tsegment{int cov[maxn<<2],v[maxn<<2];void cover(int p,int va){v[p]=min(v[p],va),cov[p]=min(cov[p],va);}void down(int p){if (cov[p]!=inf) cover(ls,cov[p]),cover(rs,cov[p]),cov[p]=inf;}void build(int p,int l,int r){cov[p]=v[p]=inf;if (l==r) return;build(ls,l,mid),build(rs,mid+1,r);}void modify(int p,int l,int r,int a,int b,int va){if (l==a&&r==b){cover(p,va);return;}down(p);if (b<=mid) modify(ls,l,mid,a,b,va);else if (a>mid) modify(rs,mid+1,r,a,b,va);else modify(ls,l,mid,a,mid,va),modify(rs,mid+1,r,mid+1,b,va);}void query(int p,int l,int r){if (l==r){ans[l]=v[p];return;}down(p),query(ls,l,mid),query(rs,mid+1,r);}void modify(int l,int r,int va){modify(1,1,len-1,l,r,va);}void query(){query(1,1,len-1);}}Tree;using namespace __gnu_pbds;priority_queue<PI,std::greater<PI>,pairing_heap_tag> q;int que[maxm+10],head,tail;bool vis[maxn],inpath[maxm];void add(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}void dijkstra(int s,int dis[]){q.push(mp(dis[s]=0,s)),inf=dis[0];static bool upd[maxn];memset(upd+1,0,sizeof(bool)*n);while (!q.empty()){PI x=q.top();q.pop();if (upd[x.id]) continue;upd[x.id]=1;for (int y=now[x.id];y;y=pre[y])if (x.dist+val[y]<dis[son[y]]) q.push(mp(dis[son[y]]=x.dist+val[y],son[y]));}}void getway(){for (int x=S,last=-1;;){pos[x]=++len,idx[len]=x;if (x==T) break;for (int y=now[x];y;y=pre[y])if (son[y]!=last&&ds[x]+val[y]+dt[son[y]]==ds[T]){last=x,x=son[y],inpath[y>>1]=1;break;}}}void getfir(int s,int dis[],int fir[]){que[tail=1]=s,fir[s]=s,head=0;while (head!=tail){int x=que[++head>maxm?1:head];for (int y=now[x];y;y=pre[y])if (!pos[son[y]]&&!fir[son[y]]&&dis[son[y]]==dis[x]+val[y])que[++tail>maxm?1:tail]=son[y],fir[son[y]]=s;}}int main(){//freopen("boss8.in","r",stdin);scanf("%d%d",&n,&m);int z;//for (int i=1,x,y;i<=m;i++){scanf("%d%d%d",&x,&y,&z);if (x>y) swap(x,y);E[i]=(Edge){x,y,z};add(x,y,z),add(y,x,z);}S=1,T=n;memset(ds,63,sizeof(int)*(n+1)),dijkstra(S,ds);memset(dt,63,sizeof(int)*(n+1)),dijkstra(T,dt);getway();//int t1=(int)clock();for (int i=1;i<=len;i++) getfir(idx[i],ds,fs);for (int i=len;i;i--) getfir(idx[i],dt,ft);//int t2=(int)clock();printf("step1 %d\n",t2-t1);Tree.build(1,1,len-1);for (int i=1;i<=m;i++){int u=E[i].u,v=E[i].v;int w=E[i].w;if (!fs[u]||!fs[v]||inpath[i]) continue;if (pos[fs[u]]<pos[ft[v]]) Tree.modify(pos[fs[u]],pos[ft[v]]-1,ds[u]+dt[v]+w);if (pos[fs[v]]<pos[ft[u]]) Tree.modify(pos[fs[v]],pos[ft[u]]-1,ds[v]+dt[u]+w);}Tree.query();//for (int i=1;i<len;i++) printf("%d\n",ans[i]);for (int i=1;i<len;i++) res=max(res,ans[i]);for (int i=1;i<len;i++) cnt+=(ans[i]==res);printf("%d %d\n",res,res==ds[T]?m:cnt);//return 0;}


1 0
原创粉丝点击