社区讨论
警示后人,一个奇怪的地方
P3008[USACO11JAN] Roads and Planes G参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miacwver
- 此快照首次捕获于
- 2025/11/22 22:00 4 个月前
- 此快照最后确认于
- 2025/11/22 23:16 4 个月前
一开始的队列入队不应该强制S所在联通块入队
这份代码就WA了
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=50005,INF=1e17;
ll n,R,S,P,sum,vis[maxn],deg[maxn],dis[maxn];
bool vit[maxn];
struct edge{
ll v,w;
friend bool operator < (edge x,edge y){
return x.w>y.w;
}
};
vector <edge> node[maxn];
vector <ll> c[maxn];
queue <ll> q;
void dfs(ll u){
c[sum].push_back(u);
vis[u]=sum;
for(auto [v,w]:node[u]){
if(vis[v]) continue;
dfs(v);
}
}
int main(){
cin>>n>>R>>P>>S;
for(int i=1;i<=R;i++){
ll u,v,w;
cin>>u>>v>>w;
node[u].push_back({v,w});
node[v].push_back({u,w});
}
for(int i=1;i<=n;i++){
if(vis[i]) continue;
sum++;
dfs(i);
}
for(int i=1;i<=P;i++){
ll u,v,w;
cin>>u>>v>>w;
deg[vis[v]]++;
node[u].push_back({v,w});
}
q.push(vis[S]);//直接入队
for(int i=1;i<=sum;i++)
if(deg[i]==0&&i!=vis[S])
q.push(i);
for(int i=1;i<=n;i++) dis[i]=INF;
dis[S]=0;
while(!q.empty()){
ll x=q.front();
q.pop();
priority_queue <edge> pq;
for(auto u:c[x])
pq.push({u,dis[u]});
memset(vit,0,sizeof(vit));
while(!pq.empty()){
auto [u,d]=pq.top();
pq.pop();
if(vit[u]) continue;
vit[u]=1;
for(auto [v,w]:node[u]){
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(vis[u]==vis[v])
pq.push({v,dis[v]});
}
if(vis[u]!=vis[v]){
deg[vis[v]]--;
if(deg[vis[v]]==0)
q.push(vis[v]);
}
}
}
}
for(int i=1;i<=n;i++){
if(dis[i]>INF/2)
cout<<"NO PATH"<<endl;
else
cout<<dis[i]<<endl;
}
return 0;
}
仅修改这一处就AC:
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=50005,INF=1e17;
ll n,R,S,P,sum,vis[maxn],deg[maxn],dis[maxn];
bool vit[maxn];
struct edge{
ll v,w;
friend bool operator < (edge x,edge y){
return x.w>y.w;
}
};
vector <edge> node[maxn];
vector <ll> c[maxn];
queue <ll> q;
void dfs(ll u){
c[sum].push_back(u);
vis[u]=sum;
for(auto [v,w]:node[u]){
if(vis[v]) continue;
dfs(v);
}
}
int main(){
cin>>n>>R>>P>>S;
for(int i=1;i<=R;i++){
ll u,v,w;
cin>>u>>v>>w;
node[u].push_back({v,w});
node[v].push_back({u,w});
}
for(int i=1;i<=n;i++){
if(vis[i]) continue;
sum++;
dfs(i);
}
for(int i=1;i<=P;i++){
ll u,v,w;
cin>>u>>v>>w;
deg[vis[v]]++;
node[u].push_back({v,w});
}
for(int i=1;i<=sum;i++)
if(deg[i]==0)//入队度为0的点
q.push(i);
for(int i=1;i<=n;i++) dis[i]=INF;
dis[S]=0;
while(!q.empty()){
ll x=q.front();
q.pop();
priority_queue <edge> pq;
for(auto u:c[x])
pq.push({u,dis[u]});
memset(vit,0,sizeof(vit));
while(!pq.empty()){
auto [u,d]=pq.top();
pq.pop();
if(vit[u]) continue;
vit[u]=1;
for(auto [v,w]:node[u]){
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(vis[u]==vis[v])
pq.push({v,dis[v]});
}
if(vis[u]!=vis[v]){
deg[vis[v]]--;
if(deg[vis[v]]==0)
q.push(vis[v]);
}
}
}
}
for(int i=1;i<=n;i++){
if(dis[i]>INF/2)
cout<<"NO PATH"<<endl;
else
cout<<dis[i]<<endl;
}
return 0;
}
但是第二篇题解是这样写的:
CPP#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 50005, M = 100005;
int n, r, p, s;
struct Edge{
int v, next, w;
}e[M << 1];
struct node{
int d, u;
bool operator < (const node &A) const {
return d > A.d;
}
};
int head[N], tot;
void adde(int u, int v, int w) {
e[tot].v = v; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++;
}
bool vis[N] ;
int cnt;
int bl[N], in[N];
int d[N] ;
vector <int> block[N];
void dfs(int u) {
vis[u] = 1;
bl[u] = cnt;
block[cnt].push_back(u) ;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(vis[v]) continue ;
dfs(v) ;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> r >> p >> s;
memset(head, -1, sizeof(head)) ;
for(int i = 1; i <= r; i++) {
int a, b, c;
cin >> a >> b >> c;
adde(a, b, c);
adde(b, a, c);
}
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
cnt++;
dfs(i) ;
}
}
for(int i = 1; i <= p; i++) {
int a, b, c;
cin >> a >> b >> c;
adde(a, b, c) ;
in[bl[b]]++;
}
memset(vis, 0, sizeof(vis)) ;
memset(d, 0x7f, sizeof(d)) ;
d[s] = 0;
queue <int> Q;
Q.push(bl[s]) ;
for(int i = 1; i <= cnt; i++) if(!in[i]) Q.push(i) ;
priority_queue <node> q;
while(!Q.empty()) {
int blo = Q.front();Q.pop() ;
for(auto u : block[blo])
q.push(node{d[u], u}) ;
while(!q.empty()) {
node now = q.top(); q.pop();
int u = now.u;
if(vis[u]) continue ;
vis[u] = 1;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(d[v] > d[u] + e[i].w) {
d[v] = d[u] + e[i].w;
if(bl[v] == bl[u]) q.push(node{d[v],v}) ;
}
if(bl[v] != bl[u] && (--in[bl[v]]) == 0) Q.push(bl[v]) ;
}
}
}
for(int i = 1; i <= n; i++) {
if(d[i] > INF) cout << "NO PATH" << '\n' ;
else cout << d[i] << '\n' ;
}
return 0;
}
居然也AC了,看不出来是怎么回事,留待后人思考了
回复
共 0 条回复,欢迎继续交流。
正在加载回复...