正则表达式

缩点后再加边的方法要记住......

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 } 
原文地址:https://www.cnblogs.com/lcan/p/9566423.html