关于链式前向星和vector建图

P1993 小 K 的农场

上面的链接挂错了,实际是这个[链式前向星建图 55pts](https://www.luogu.com.cn/record/144726766)
by hzoi_Shadow @ 2024-01-28 07:08:22


你都不放代码我看什么。 题解里第一篇就是链式前向星写法,只能说大概你链式前向星写挂了。
by strcmp @ 2024-01-28 07:15:36


@[wql_cai](/user/551861) ```cpp 链式前向星 #include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define sort stable_sort #define endl '\n' struct node { int nxt,to,w; }e[30000]; int head[30000],vis[30000],dis[30000],num[30000],cnt=0,flag=0; inline void add(int u,int v,int w) { cnt++; e[cnt].nxt=head[u]; e[cnt].to=v; e[cnt].w=w; head[u]=cnt; } void spfa(int s) { vis[s]=1; for(int i=head[s];i!=0;i=e[i].nxt) { if(dis[e[i].to]<dis[s]+e[i].w) { dis[e[i].to]=dis[s]+e[i].w; if(vis[e[i].to]==1||flag==1) { flag=0; cout<<"No"<<endl; exit(0); } spfa(e[i].to); } } vis[s]=0; } int main() { int n,m,i,u,v,w,pd; scanf("%d%d",&n,&m); memset(vis,0,sizeof(vis)); memset(dis,-0x3f,sizeof(dis)); for(i=1;i<=n;i++) { add(0,i,0); } for(i=1;i<=m;i++) { scanf("%d%d%d",&pd,&u,&v); if(pd==1||pd==2) { scanf("%d",&w); } if(pd==1) { add(v,u,w); } if(pd==2) { add(u,v,-w); } if(pd==3) { add(u,v,0); add(v,u,0); } } dis[0]=0x7f7f7f7f; spfa(0); if(flag==0) { cout<<"Yes"<<endl; } return 0; } ``` ```cpp vector #include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define sort stable_sort #define endl '\n' vector<pair<int,int> >e[30000]; int vis[30000],dis[30000],num[30000],cnt=0; bool spfa(int s) { vis[s]=1; for(int i=0;i<e[s].size();i++) { if(dis[e[s][i].first]<dis[s]+e[s][i].second) { dis[e[s][i].first]=dis[s]+e[s][i].second; if(vis[e[s][i].first]==1||spfa(e[s][i].first)==false) { return false; } } } vis[s]=0; return true; } int main() { int n,m,i,u,v,w,pd; cin>>n>>m; memset(vis,0,sizeof(vis)); memset(dis,-0x3f,sizeof(dis)); for(i=1;i<=n;i++) { e[0].push_back(make_pair(i,0)); } for(i=1;i<=m;i++) { cin>>pd>>u>>v; if(pd==1||pd==2) { cin>>w; } if(pd==1) { e[v].push_back(make_pair(u,w)); } if(pd==2) { e[u].push_back(make_pair(v,-w)); } if(pd==3) { e[u].push_back(make_pair(v,0)); e[v].push_back(make_pair(u,0)); } } dis[0]=0x7f7f7f7f; if(spfa(0)==true) { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } return 0; } ```
by hzoi_Shadow @ 2024-01-28 07:35:58


同上,为什么链式前项星比vector慢这么多? - 链式前项星 ```cpp #include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,P=1e9+7; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0; for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } int n,m,d[N]; int head[N],nxt[N],to[N],w[N],tot; bool v[N]; void add(int x,int y,int z) { nxt[++tot]=head[x]; to[tot]=y; w[tot]=z; head[x]=tot; } bool spfa(int x) { v[x]=1; for(int i=head[x];i!=-1;i=nxt[i]) { int y=to[i],z=w[i]; if(d[y]>d[x]+z) { d[y]=d[x]+z; if(v[y]||!spfa(y)) return 0; } } v[x]=0; return 1; } signed main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif read(n),read(m); int s,x,y,z; for(int i=0;i<=n;i++) head[i]=-1; for(int i=1;i<=m;i++) { read(s); if(s==1) read(x),read(y),read(z), add(x,y,~z+1); else if(s==2) read(x),read(y),read(z), add(y,x,z); else read(x),read(y), add(x,y,0),add(y,x,0); } for(int i=1;i<=n;i++) add(0,i,0); memset(d,0x3f,sizeof(d)); d[0]=0; cout<<(spfa(0)?"Yes":"No"); } ``` - vector ```cpp #include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,P=1e9+7; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0; for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } int n,m,d[N]; bool v[N]; vector<pair<int,int>>e[N]; bool spfa(int x) { v[x]=1; for(int i=0;i<e[x].size();i++) { int y=e[x][i].first,z=e[x][i].second; if(d[y]>d[x]+z) { d[y]=d[x]+z; if(v[y]||!spfa(y)) return 0; } } v[x]=0; return 1; } signed main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif read(n),read(m); int s,x,y,z; for(int i=1;i<=m;i++) { read(s); if(s==1) read(x),read(y),read(z), e[x].push_back(make_pair(y,-z)); else if(s==2) read(x),read(y),read(z), e[y].push_back(make_pair(x,z)); else read(x),read(y), e[x].push_back(make_pair(y,0)), e[y].push_back(make_pair(x,0)); } for(int i=1;i<=n;i++) e[0].push_back(make_pair(i,0)); memset(d,0x3f,sizeof(d)); d[0]=0; cout<<(spfa(0)?"Yes":"No"); } ``` vector AC了,链式前项星挂55TLE
by Charlie_ljk @ 2024-01-28 07:50:38


都是用 DFS 打的,但vector就没有被卡
by Charlie_ljk @ 2024-01-28 07:53:40


@[The_Shadow_Dragon](/user/848964) @[Charlie_ljk](/user/1055198) 遍历顺序的问题,可以把边打乱: [R](https://www.luogu.com.cn/record/144728004) ```cpp #include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define sort stable_sort #define endl '\n' struct node { int nxt,to,w; }e[30000]; int head[30000],vis[30000],dis[30000],num[30000],cnt=0; inline void add(int u,int v,int w) { cnt++; e[cnt].nxt=head[u]; e[cnt].to=v; e[cnt].w=w; head[u]=cnt; } inline bool spfa(int s) { vis[s]=1; for(int i=head[s];i!=0;i=e[i].nxt) { if(dis[e[i].to]<dis[s]+e[i].w) { dis[e[i].to]=dis[s]+e[i].w; if(vis[e[i].to]==1||spfa(e[i].to)==false) { return false; } } } vis[s]=0; return true; } int main() { int n,m,i,u,v,w,pd; scanf("%d%d",&n,&m); memset(vis,0,sizeof(vis)); memset(dis,-0x3f,sizeof(dis)); vector<tuple<int, int, int> > g; for(i=1;i<=n;i++) { //add(0,i,0); g.emplace_back(0, i, 0); } for(i=1;i<=m;i++) { scanf("%d%d%d",&pd,&u,&v); if(pd==1||pd==2) { scanf("%d",&w); } if(pd==1) { //add(v,u,w); g.emplace_back(v, u, w); } if(pd==2) { //add(u,v,-w); g.emplace_back(u, v, -w); } if(pd==3) { //add(u,v,0); //add(v,u,0); g.emplace_back(u, v, 0); g.emplace_back(v, u, 0); } } //mt19937 rd(chrono::system_clock::now().time_since_epoch().count()); //shuffle(g.begin(), g.end(), rd); reverse(g.begin(), g.end()); for (auto & [u, v, w] : g) add(u, v, w); dis[0]=0x7f7f7f7f; if(spfa(0)==true) { printf("Yes\n"); } else { printf("No\n"); } return 0; } ```
by 0x7f @ 2024-01-28 08:25:22


啊?
by Lixiang_is_potato @ 2024-01-28 09:03:46


你把vector连的点倒过来就T了 https://www.luogu.com.cn/record/144735417 具体原因是SPFA,遍历顺序不同,跑的次数应该也不同????好像是这杨
by Trump_ @ 2024-01-28 09:30:55


|