您的位置:首页 > 其它

【BZOJ】【2200】【USACO 2011 Jan】道路和航线

2015-01-28 16:33 309 查看
做了一天……

TLE:数组开小了-_-#道路是有50000的,双向要乘二。(我特么怎么想的就以为是树了……)

WA:一些大点都WA了,小点都过了。好纠结……

AC了QAQ,不知道为什么,在并查集合并的时候写成fa[x]=y就会WA,写成fa[y]=x就AC……这不是一样的吗?

(虽然说是fa[y]=x是把出边到达的节点的fa都置为x,好像更符合人的思维= =)

Update:由于是宽搜,所以是有“祖先后代“关系的,如果写成fa[x]=y就相当于把所有的祖先后代关系反过来……当然原本是同一系的关系就会变得分裂开了!

/**************************************************************
Problem: 2200
User: Tunix
Language: C++
Result: Accepted
Time:688 ms
Memory:5432 kb
****************************************************************/

//BZOJ 2200
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
void read(int &v){
v=0; int sign=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
v*=sign;
}
/******************tamplate*********************/
const int N=55010,INF=1e9;
int to[N<<1],next[N<<1],head
,len[N<<1],cnt;
inline void add(int x,int y,int z){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=z;
to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt; len[cnt]=z;
}
int t
,ne
,h
,l
,tot;
inline void ins(int x,int y,int z){
t[++tot]=y; ne[tot]=h[x]; h[x]=tot; l[tot]=z;
}
/*******************edge************************/
int in
,n,R,P,S;
struct node{
int dist,num;
bool operator < (const node &now)const{
return dist>now.dist;
}
};
int dist
;
priority_queue<node>Q;
bool done
;
queue<int>tp;//拓扑
int fa
;
int find(int x){ return fa[x]==x ? x : (fa[x]=find(fa[x]));}

vector<int>have
;
void dijkstra(int x){
int temp=0;
rep(i,have[x].size()){
temp=have[x][i];
Q.push((node){dist[temp],temp});
}
while(!Q.empty()){
int now=Q.top().num; Q.pop();
if (done[now]) continue;
done[now]=1;
for(int i=head[now];i;i=next[i]){
if (dist[to[i]]>dist[now]+len[i]){
dist[to[i]]=dist[now]+len[i];
Q.push((node){dist[to[i]],to[i]});
}
}
for(int i=h[now];i;i=ne[i]){
int set=find(t[i]);
if (dist[t[i]]>dist[now]+l[i]){
dist[t[i]]=dist[now]+l[i];
have[set].pb(t[i]);
}
in[set]--;
if (in[set]==0) tp.push(set);
}
}
}
/******************dijkstra*********************/
bool vis
;
void bfs(){
queue<int>q;
vis[S]=1; q.push(S);
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=next[i])
if (!vis[to[i]]) vis[to[i]]=1,q.push(to[i]);
for(int i=h[x];i;i=ne[i]){
++in[find(t[i])];
if (!vis[t[i]]) vis[t[i]]=1, q.push(t[i]);;
}
}
}
void solve(){
F(i,1,n) fa[i]=i;
F(i,1,n){
int x=find(i),y;
for(int j=head[i];j;j=next[j]){
y=find(to[j]);
if (x!=y) fa[y]=x;//就是这里!!!想不通啊想不通
}
}
bfs();
//ready
F(i,1,n) { dist[i]=INF;done[i]=0;}
dist[S]=0;
tp.push(find(S));
have[find(S)].pb(S);
//end
while(!tp.empty()){
dijkstra(tp.front());
tp.pop();
}
F(i,1,n)
if (dist[i]!=INF) printf("%d\n",dist[i]);
else printf("NO PATH\n");
}
int main(){
read(n); read(R); read(P); read(S);
int x,y,z;
F(i,1,R){
read(x); read(y); read(z);
add(x,y,z);
}
F(i,1,P){
read(x); read(y); read(z);
ins(x,y,z);
}
solve();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: