Gym - 101986F

這是一個很是nice的題:
1.map去重邊,n的話有1e5,node

1 const long long base[]={20200422,1000000007,9997,7};
2 mp[E[i].l*base[1]+E[i].r*base[2]+E[i].v*base[3]]++;


這樣來判斷這條邊的個數ios

2.結構體封裝
好處:一樣的函數不用再寫好多個了,總體美觀大方簡潔
壞處:若是不用屢次調用其實沒有必要封裝函數

3.邊有編號的問題大數據

1 struct edge{
2 long long l,r,v;
3 }E[N];

直接這樣存第i個邊的信息spa

依然跑前向星,不過有所改變code

 1 For(i,1,m){
 2         in(E[i].l);in(E[i].r);in(E[i].v);
 3         G1.push(E[i].l,E[i].r,E[i].v,i);
 4         G2.push(E[i].r,E[i].l,E[i].v,i);
 5         mp[E[i].l*base[1]+E[i].r*base[2]+E[i].v*base[3]]++;
 6     }
 7 
 8 void push(long long x,long long y,long long v,long long id){
 9         node *p;
10         p=new node();
11         p->n=y;
12         p->v=v;
13         p->id=id;
14         if(e[x]==0)
15                 e[x]=p;
16         else{
17                 p->next=e[x]->next;
18                 e[x]->next=p;
19         }
20 }

這樣就知道了這條邊的編號。blog

4.這個題目的大意是把圖中某一條邊反轉以後會致使最短路變小變大仍是不變,這個題的想法自己就很妙
設起點爲s,終點爲t,先求出來s到全部點的最短路,再把邊反向求t到全部點的最短路,即G1.spfa(1);G2.spfa(2);get

再把組成圖中最短路的全部的邊全都拿出來再建一個新圖string

1     For(i,1,m){
2         if(G1.d[E[i].l]+G2.d[E[i].r]+E[i].v==G1.d[2]){
3             G3.push(E[i].l,E[i].r,E[i].v,i);
4             G3.push(E[i].r,E[i].l,E[i].v,i);
5         }
6     }

新圖上的橋是全部最短路的必經邊,在這個新圖上縮點,剩下的邊都是橋,可是能夠在跑tarjan的時候直接判了it

 1     void tarjan(long long x,long long fa){
 2         dfn[x]=low[x]=++cnt;
 3         vis[x]=1;
 4         for(node *i=e[x];i;i=i->next){
 5             if(i->n==fa) continue;
 6             if(!dfn[i->n]){
 7                 tarjan(i->n,x);
 8                 low[x]=min(low[x],low[i->n]);
 9                 if(low[i->n]>dfn[x]) bi[i->id]=1;//就是這裏
10             }
11             else
12                 if(vis[i->n])
13                     low[x]=min(low[x],dfn[i->n]);
14         }
15     }

爲何這樣能夠呢?由於i->n繞了一圈也沒能翻上去,因此第i->id條邊自己就是橋

最後是答案的判斷:

1     For(i,1,m){
2         if(G1.d[E[i].r]+G2.d[E[i].l]+E[i].v<G1.d[2]) puts("HAPPY");
3         else if(bi[i]&&mp[E[i].l*base[1]+E[i].r*base[2]+E[i].v*base[3]]==1) puts("SAD");
4         else puts("SOSO");
5     }

原本是 s------>u------->v------>t

反轉後 s------>v------->u------>t
看看新的路是否是比原來的路短,短就HAPPY
不然若是是反轉了全部最短路必經路,那麼那條路就走不通了,要麼不可到達,要麼只能走其餘不太優的路最終致使最短路變長,也就是SAD了
其餘的都是SOSO,由於反轉了非必經路,走其餘最短路就行了,不影響。

5.spfa的初始化問題

For(i,0,n) d[i]=inf;


這個inf要足夠大,我設的2147483647竟然小了qwq,卡了很久,還有就是若是對拍的時候跑了好久都沒掛,極可能程序是對的可是到大數據的時候出了問題

 

 

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <queue>
  4 #include <algorithm>
  5 #include <map>
  6 #include <cstring>
  7 #define inf 23333333333333
  8 #define N 1000010
  9 #define p(a) putchar(a)
 10 #define For(i,a,b) for(long long i=a;i<=b;++i)
 11 
 12 using namespace std;
 13 const long long base[]={20200422,1000000007,9997,7};
 14 long long n,m;
 15 bool bi[N];
 16 map<long long,long long>mp;
 17 void in(long long &x){
 18     long long y=1;char c=getchar();x=0;
 19     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
 20     while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
 21     x*=y;
 22 }
 23 void o(long long x){
 24     if(x<0){p('-');x=-x;}
 25     if(x>9)o(x/10);
 26     p(x%10+'0');
 27 }
 28 
 29 struct edge{
 30     long long l,r,v;
 31 }E[N];
 32 
 33 struct Graph{
 34     long long cnt;
 35     long long d[N],low[N],dfn[N];
 36     bool vis[N];
 37     deque<long long>q;
 38     struct node{
 39         long long n;
 40         long long v;
 41         long long id;
 42         node *next;
 43     }*e[N];
 44 
 45     void push(long long x,long long y,long long v,long long id){
 46         node *p;
 47         p=new node();
 48         p->n=y;
 49         p->v=v;
 50         p->id=id;
 51         if(e[x]==0)
 52             e[x]=p;
 53         else{
 54             p->next=e[x]->next;
 55             e[x]->next=p;
 56         }
 57     }
 58 
 59     void spfa(long long s){
 60         For(i,0,n) d[i]=inf;
 61         d[s]=0;
 62         q.push_front(s);
 63         while(!q.empty()){
 64             long long x=q.front();q.pop_front();
 65             vis[x]=1;
 66             for(node *i=e[x];i;i=i->next){
 67                 if(d[i->n]>d[x]+i->v){
 68                     d[i->n]=d[x]+i->v;
 69                     if(!vis[i->n]){
 70                         if(!q.empty()&&d[i->n]<d[q.front()]) q.push_front(i->n);
 71                         else q.push_back(i->n);
 72                         vis[i->n]=1;
 73                     }
 74                 }
 75             }
 76             vis[x]=0;            
 77         }
 78     }
 79 
 80     void tarjan(long long x,long long fa){
 81         dfn[x]=low[x]=++cnt;
 82         vis[x]=1;
 83         for(node *i=e[x];i;i=i->next){
 84             if(i->n==fa) continue;
 85             if(!dfn[i->n]){
 86                 tarjan(i->n,x);
 87                 low[x]=min(low[x],low[i->n]);
 88                 if(low[i->n]>dfn[x]) bi[i->id]=1;
 89             }
 90             else
 91                 if(vis[i->n])
 92                     low[x]=min(low[x],dfn[i->n]);
 93         }
 94     }
 95 }G1,G2,G3;
 96 
 97 signed main(){
 98     in(n);in(m);
 99     For(i,1,m){
100         in(E[i].l);in(E[i].r);in(E[i].v);
101         G1.push(E[i].l,E[i].r,E[i].v,i);
102         G2.push(E[i].r,E[i].l,E[i].v,i);
103         mp[E[i].l*base[1]+E[i].r*base[2]+E[i].v*base[3]]++;
104     }
105     G1.spfa(1);G2.spfa(2);
106     For(i,1,m){
107         if(G1.d[E[i].l]+G2.d[E[i].r]+E[i].v==G1.d[2]){
108             G3.push(E[i].l,E[i].r,E[i].v,i);
109             G3.push(E[i].r,E[i].l,E[i].v,i);
110         }
111     }
112     G3.tarjan(1,1);
113     For(i,1,m){
114         if(G1.d[E[i].r]+G2.d[E[i].l]+E[i].v<G1.d[2]) puts("HAPPY");
115         else if(bi[i]&&mp[E[i].l*base[1]+E[i].r*base[2]+E[i].v*base[3]]==1) puts("SAD");
116         else puts("SOSO");
117     }
118     return 0;
119 }
相關文章
相關標籤/搜索