缩点后再加边的方法要记住......
dijkstra和spfa在洛谷上都能过
1 #include<iostream> 2 #include<cstdio> 3 #include<stack> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn=2e5+7; 8 const int maxm=1e6+7; 9 int n,m,num,num2,cnt,tot; 10 int head[maxn],head2[maxn],dfn[maxn],low[maxn],color[maxn]; 11 int d[maxn]; 12 bool ins[maxn],vis[maxn],inq[maxn]; 13 stack<int>s; 14 typedef pair<int,int> pii; 15 priority_queue<pii,vector<pii>,greater<pii> > q; 16 struct Edge{ 17 int next,to,dis,from; 18 }edge[maxm],edge2[maxm]; 19 void add(int from,int to,int dis){ 20 edge[++num].next=head[from]; 21 edge[num].from=from; 22 edge[num].to=to; 23 edge[num].dis=dis; 24 head[from]=num; 25 } 26 void add2(int from,int to,int dis){ 27 edge2[++num2].next=head2[from]; 28 edge2[num2].from=from; 29 edge2[num2].to=to; 30 edge2[num2].dis=dis; 31 head2[from]=num2; 32 } 33 void tarjan(int x){ 34 dfn[x]=low[x]=++cnt; 35 ins[x]=true;s.push(x); 36 for(int i=head[x];i;i=edge[i].next){ 37 int v=edge[i].to; 38 if(!dfn[v]){ 39 tarjan(v); 40 low[x]=min(low[x],low[v]); 41 } 42 else if(ins[v]==true) low[x]=min(low[x],dfn[v]); 43 } 44 int k; 45 if(dfn[x]==low[x]){ 46 tot++; 47 do{ 48 k=s.top();s.pop(); 49 color[k]=tot;ins[k]=false; 50 }while(k!=x); 51 } 52 } 53 void dijkstra(){ 54 memset(d,0x3f3f3f3f,sizeof(d)); 55 d[color[1]]=0;q.push(make_pair(0,color[1])); 56 while(!q.empty()){ 57 int u=q.top().second;q.pop(); 58 if(inq[u]) continue; 59 inq[u]=true; 60 for(int i=head2[u];i;i=edge2[i].next){ 61 int v=edge2[i].to; 62 if(d[v]>d[u]+edge2[i].dis){ 63 d[v]=d[u]+edge2[i].dis; 64 q.push(make_pair(d[v],v)); 65 } 66 } 67 } 68 } 69 int main(){ 70 cin>>n>>m; 71 for(int i=1;i<=m;i++){ 72 int u,v,w;cin>>u>>v>>w; 73 add(u,v,w); 74 } 75 tarjan(1); 76 for(int u=1;u<=n;u++){ 77 memset(vis,0,sizeof(vis)); 78 for(int i=head[u];i;i=edge[i].next){ 79 int v=edge[i].to; 80 if(!vis[color[v]]){ 81 vis[color[v]]=true; 82 add2(color[u],color[v],edge[i].dis); 83 } 84 } 85 } 86 for(int i=1;i<=m;i++){ 87 if(color[edge[i].from]==color[edge[i].to]) continue; 88 else add2(color[edge[i].from],color[edge[i].to],edge[i].dis); 89 } 90 dijkstra(); 91 cout<<d[color[n]]<<endl; 92 return 0; 93 }
1 #include<iostream> 2 #include<cstdio> 3 #include<stack> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn=2e5+7; 8 const int maxm=1e6+7; 9 int n,m,num,num2,cnt,tot; 10 int head[maxn],head2[maxn],dfn[maxn],low[maxn],color[maxn]; 11 int d[maxn]; 12 bool ins[maxn],vis[maxn],inq[maxn]; 13 stack<int>s; 14 queue<int>q; 15 struct Edge{ 16 int next,to,dis,from; 17 }edge[maxm],edge2[maxm]; 18 void add(int from,int to,int dis){ 19 edge[++num].next=head[from]; 20 edge[num].from=from; 21 edge[num].to=to; 22 edge[num].dis=dis; 23 head[from]=num; 24 } 25 void add2(int from,int to,int dis){ 26 edge2[++num2].next=head2[from]; 27 edge2[num2].from=from; 28 edge2[num2].to=to; 29 edge2[num2].dis=dis; 30 head2[from]=num2; 31 } 32 void tarjan(int x){ 33 dfn[x]=low[x]=++cnt; 34 ins[x]=true;s.push(x); 35 for(int i=head[x];i;i=edge[i].next){ 36 int v=edge[i].to; 37 if(!dfn[v]){ 38 tarjan(v); 39 low[x]=min(low[x],low[v]); 40 } 41 else if(ins[v]==true) low[x]=min(low[x],dfn[v]); 42 } 43 int k; 44 if(dfn[x]==low[x]){ 45 tot++; 46 do{ 47 k=s.top();s.pop(); 48 color[k]=tot;ins[k]=false; 49 }while(k!=x); 50 } 51 } 52 void spfa(){ 53 memset(d,0x3f3f3f3f,sizeof(d)); 54 d[color[1]]=0;q.push(color[1]);inq[color[1]]=true; 55 while(!q.empty()){ 56 int u=q.front();q.pop(); 57 for(int i=head2[u];i;i=edge2[i].next){ 58 int v=edge2[i].to; 59 if(d[v]>d[u]+edge2[i].dis){ 60 d[v]=d[u]+edge2[i].dis; 61 if(!inq[v]){ 62 q.push(v);inq[v]=true; 63 } 64 } 65 } 66 } 67 } 68 int main(){ 69 cin>>n>>m; 70 for(int i=1;i<=m;i++){ 71 int u,v,w;cin>>u>>v>>w; 72 add(u,v,w); 73 } 74 for(int i=1;i<=n;i++){ 75 if(!dfn[i]) tarjan(i); 76 } 77 for(int i=1;i<=m;i++){ 78 if(color[edge[i].from]==color[edge[i].to]) continue; 79 else add2(color[edge[i].from],color[edge[i].to],edge[i].dis); 80 } 81 spfa(); 82 cout<<d[color[n]]<<endl; 83 return 0; 84 }