【CSP模拟赛】益智游戏(最短路&拓扑排序)

匿名 (未验证) 提交于 2019-12-03 00:14:01









#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50005; const int maxm=200005; struct node{int id;long long d;}; bool operator <(node a,node b){return a.d>b.d;} int info[maxn],nx[maxm<<1],v[maxm<<1],w[maxm<<1],re[maxm<<1];long long d[5][maxn]; int n,m,en,ans,ecnt,p[5],dp[maxn],vis[maxn],inp[maxn],top[maxn],lef[maxm<<1];priority_queue<node>q; void add(int u1,int v1,int w1,int r){nx[++ecnt]=info[u1];info[u1]=ecnt;v[ecnt]=v1;w[ecnt]=w1;re[ecnt]=r;} void SPFA(int k) {     memset(vis,0,sizeof vis);     d[k][p[k]]=0;q.push((node){p[k],0});     while(!q.empty())     {         node nw=q.top();q.pop();         if(vis[nw.id]==1)continue;vis[nw.id]=1;d[k][nw.id]=nw.d;         for(int i=info[nw.id];i;i=nx[i])         if(!((k%2)^re[i])&&d[k][v[i]]>nw.d+w[i])q.push((node){v[i],nw.d+w[i]});     } } int main() {     scanf("%d%d",&n,&m);memset(d,0x7f,sizeof d);     for(int i=1,u1,v1,w1;i<=m;i++)scanf("%d%d%d",&u1,&v1,&w1),add(u1,v1,w1,1),add(v1,u1,w1,0);     for(int k=1;k<=4;k++)scanf("%d",&p[k]),SPFA(k);     if(d[1][p[2]]==d[0][0]||d[3][p[4]]==d[0][0]){puts("-1");return 0;}     for(int x=1;x<=n;x++)     {         for(int e=info[x];e;e=nx[e])         if(re[e]&&d[1][x]+w[e]+d[2][v[e]]==d[1][p[2]]&&d[3][x]+w[e]+d[4][v[e]]==d[3][p[4]])         lef[e]=1,inp[v[e]]++;     }     for(int x=1;x<=n;x++)if(inp[x]==0)top[++en]=x,dp[x]=1;     for(int i=1;i<=en;i++)     {         int nw=top[i];         for(int e=info[nw];e;e=nx[e])             if(lef[e])             {                 dp[v[e]]=max(dp[v[e]],dp[nw]+1);                 ans=max(ans,dp[v[e]]);inp[v[e]]--;                 if(!inp[v[e]])top[++en]=v[e];             }     }     printf("%d\n",ans); }

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!