Gym - 101986F
这是一个非常nice的题:
1.map去重边,n的话有1e5,
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]]++;
这样来判断这条边的个数
2.结构体封装
好处:同样的函数不用再写好多个了,整体美观大方简洁
坏处:如果不用多次调用其实没有必要封装
3.边有编号的问题
1 struct edge{ 2 long long l,r,v; 3 }E[N];
直接这样存第i个边的信息
依然跑前向星,不过有所改变
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 }
这样就知道了这条边的编号。
4.这个题目的大意是把图中某一条边反转之后会导致最短路变小变大还是不变,这个题的想法本身就很妙
设起点为s,终点为t,先求出来s到所有点的最短路,再把边反向求t到所有点的最短路,即G1.spfa(1);G2.spfa(2);
再把组成图中最短路的所有的边全都拿出来再建一个新图
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的时候直接判了
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 }