【BZOJ】【2200】【USACO 2011 Jan】道路和航线
做了一天……
TLE:数组开小了-_-#道路是有50000的,双向要乘二。(我特么怎么想的就以为是树了……)
WA:一些大点都WA了,小点都过了。好纠结……
AC了QAQ,不知道为什么,在并查集合并的时候写成fa[x]=y就会WA,写成fa[y]=x就AC……这不是一样的吗?
(虽然说是fa[y]=x是把出边到达的节点的fa都置为x,好像更符合人的思维= =)
Update:由于是宽搜,所以是有“祖先后代“关系的,如果写成fa[x]=y就相当于把所有的祖先后代关系反过来……当然原本是同一系的关系就会变得分裂开了!
1 /************************************************************** 2 Problem: 2200 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:688 ms 7 Memory:5432 kb 8 ****************************************************************/ 9 10 //BZOJ 2200 11 #include<queue> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 void read(int &v){ 23 v=0; int sign=1; char ch=getchar(); 24 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 25 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 26 v*=sign; 27 } 28 /******************tamplate*********************/ 29 const int N=55010,INF=1e9; 30 int to[N<<1],next[N<<1],head[N],len[N<<1],cnt; 31 inline void add(int x,int y,int z){ 32 to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=z; 33 to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt; len[cnt]=z; 34 } 35 int t[N],ne[N],h[N],l[N],tot; 36 inline void ins(int x,int y,int z){ 37 t[++tot]=y; ne[tot]=h[x]; h[x]=tot; l[tot]=z; 38 } 39 /*******************edge************************/ 40 int in[N],n,R,P,S; 41 struct node{ 42 int dist,num; 43 bool operator < (const node &now)const{ 44 return dist>now.dist; 45 } 46 }; 47 int dist[N]; 48 priority_queue<node>Q; 49 bool done[N]; 50 queue<int>tp;//拓扑 51 int fa[N]; 52 int find(int x){ return fa[x]==x ? x : (fa[x]=find(fa[x]));} 53 54 vector<int>have[N]; 55 void dijkstra(int x){ 56 int temp=0; 57 rep(i,have[x].size()){ 58 temp=have[x][i]; 59 Q.push((node){dist[temp],temp}); 60 } 61 while(!Q.empty()){ 62 int now=Q.top().num; Q.pop(); 63 if (done[now]) continue; 64 done[now]=1; 65 for(int i=head[now];i;i=next[i]){ 66 if (dist[to[i]]>dist[now]+len[i]){ 67 dist[to[i]]=dist[now]+len[i]; 68 Q.push((node){dist[to[i]],to[i]}); 69 } 70 } 71 for(int i=h[now];i;i=ne[i]){ 72 int set=find(t[i]); 73 if (dist[t[i]]>dist[now]+l[i]){ 74 dist[t[i]]=dist[now]+l[i]; 75 have[set].pb(t[i]); 76 } 77 in[set]--; 78 if (in[set]==0) tp.push(set); 79 } 80 } 81 } 82 /******************dijkstra*********************/ 83 bool vis[N]; 84 void bfs(){ 85 queue<int>q; 86 vis[S]=1; q.push(S); 87 while(!q.empty()){ 88 int x=q.front(); 89 q.pop(); 90 for(int i=head[x];i;i=next[i]) 91 if (!vis[to[i]]) vis[to[i]]=1,q.push(to[i]); 92 for(int i=h[x];i;i=ne[i]){ 93 ++in[find(t[i])]; 94 if (!vis[t[i]]) vis[t[i]]=1, q.push(t[i]);; 95 } 96 } 97 } 98 void solve(){ 99 F(i,1,n) fa[i]=i; 100 F(i,1,n){ 101 int x=find(i),y; 102 for(int j=head[i];j;j=next[j]){ 103 y=find(to[j]); 104 if (x!=y) fa[y]=x;//就是这里!!!想不通啊想不通 105 } 106 } 107 bfs(); 108 //ready 109 F(i,1,n) { dist[i]=INF;done[i]=0;} 110 dist[S]=0; 111 tp.push(find(S)); 112 have[find(S)].pb(S); 113 //end 114 while(!tp.empty()){ 115 dijkstra(tp.front()); 116 tp.pop(); 117 } 118 F(i,1,n) 119 if (dist[i]!=INF) printf("%d\n",dist[i]); 120 else printf("NO PATH\n"); 121 } 122 int main(){ 123 read(n); read(R); read(P); read(S); 124 int x,y,z; 125 F(i,1,R){ 126 read(x); read(y); read(z); 127 add(x,y,z); 128 } 129 F(i,1,P){ 130 read(x); read(y); read(z); 131 ins(x,y,z); 132 } 133 solve(); 134 return 0; 135 }