T7025 miaom与+1(一)

来源:互联网 发布:苹果电脑用于软件开发 编辑:程序博客网 时间:2024/05/29 14:54
以下摘自王哲凡教授的课件。
先构造出ST的最短路网。
最短路网是啥?
满足dis_(S,x)+W_(x,y)+dis_(y,T)=dis_(S,T)的边(x,y)组成的图。
然后在最短路网上dpS到每个点x的路径条数P_x 和每个点xT的路径条数Q_x
P_T=Q_S=Z
一个点x为必经点当且仅当Z=P_x Q_x
一条边(x,y)为必经边当且仅当Z=P_x Q_y
路径数太大爆longlong怎么办?
随便找个好看的数取模就好了嘛。
时间复杂度O((n+m)  logm)大概
下面是我写的代码。
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<algorithm>#include<set>#include<bitset>#include<queue>using namespace std;#define rep(i,j,k) for(i=j;i<=k;++i)#define per(i,j,k) for(i=j;i>=k;--i)#define G getchar()#define LL long long#define pii pair<int,int>#define mkp make_pair#define X first#define Y second#define N 100005#define NN 300005#define inf=300000000priority_queue<pii,vector<pii>,greater<pii> >pq;int n,m,s,t;struct EDGE{int a,b,w;}e[NN];int rhe[N],he[N],ne[NN<<1],to[NN<<1],W[NN<<1],tot;int d[N],rd[N],md;bool vis[N];int q[N],in[N],rin[N],f[N],rf[N],sum;int ans[N],cnt;void read(int &x){char ch=G;while(ch<48||ch>57)ch=G;for(x=0;ch>47&&ch<58;ch=G)x=x*10+ch-48;}void add(int x,int y,int z){to[++tot]=y;W[tot]=z;ne[tot]=he[x];he[x]=tot;to[++tot]=x;W[tot]=z;ne[tot]=rhe[y];rhe[y]=tot;}void dijkstra(){int i,x,y,tmp;memset(d,63,sizeof d);pq.push(mkp(d[s]=0,s));while(!pq.empty()){x=pq.top().Y;pq.pop();if(vis[x])continue;vis[x]=1;for(i=he[x];i;i=ne[i])if((tmp=d[x]+W[i])<d[y=to[i]])pq.push(mkp(d[y]=tmp,y));}md=d[t];}void rdijkstra(){memset(vis,0,sizeof vis);int i,x,y,tmp;memset(rd,63,sizeof rd);pq.push(mkp(rd[t]=0,t));while(!pq.empty()){x=pq.top().Y;pq.pop();if(vis[x])continue;vis[x]=1;for(i=rhe[x];i;i=ne[i])if((tmp=rd[x]+W[i])<rd[y=to[i]])pq.push(mkp(rd[y]=tmp,y));}}void dp(){int Ft=1,Rr=2,u,v,i;for(f[q[1]=s]=1;Ft<Rr;){for(i=he[u=q[Ft++]];i;i=ne[i]){f[v=to[i]]+=f[u];if(!(--in[v]))q[Rr++]=v;}}sum=f[t];}void rdp(){int Ft=1,Rr=2,u,v,i;for(rf[q[1]=t]=1;Ft<Rr;){for(i=rhe[u=q[Ft++]];i;i=ne[i]){rf[v=to[i]]+=rf[u];if(!(--rin[v]))q[Rr++]=v;}}}int main(){int i;read(n);read(m);read(s);read(t);rep(i,1,m){read(e[i].a);read(e[i].b);read(e[i].w);add(e[i].a,e[i].b,e[i].w);}dijkstra();rdijkstra();memset(he,0,sizeof he);memset(rhe,0,sizeof rhe);tot=0;rep(i,1,m)if(d[e[i].a]+e[i].w+rd[e[i].b]==md)add(e[i].a,e[i].b,e[i].w),++in[e[i].b],++rin[e[i].a];dp();rdp();rep(i,1,n)if(f[i]*rf[i]==sum)ans[++cnt]=i;printf("%d\n",cnt);sort(ans+1,ans+1+cnt);rep(i,1,cnt)printf("%d ",ans[i]);puts("");return 0;}


原创粉丝点击