P3905 道路重建
P3905 道路重建
我一开始想错了,我的是类似kruskal,把毁坏的边从小到大加,并且判断联通性。但是这有一个问题,你可能会多加,就是这条边没用,但是它比较小,你也加上了。
居然还有10分,数据也是水水的。。。
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #define inf 2147483647 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() //by war //2017.10.10 using namespace std; int n,m,dd,A,B,x,y,v,t; int a[110][110]; bool b[110][110]; int d[110]; int ans; struct node { int l,r,v; bool operator<(const node&aa)const { return v<aa.v; } }e[10000]; void in(int &x) { char c=g();x=0; while(c<'0'||c>'9')c=g(); while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); } void o(int x) { if(x>9)o(x/10); p(x%10+'0'); } int find(int x) { if(d[x]==x)return x; d[x]=find(d[x]); return d[x]; } int main() { in(n),in(m); For(i,1,n) d[i]=i; For(i,1,m) { in(x),in(y),in(v); a[x][y]=v; a[y][x]=v; } in(dd); For(i,1,dd) { in(x),in(y); b[x][y]=true; b[y][x]=true; } in(A),in(B); For(i,1,n) For(j,1,n) { if(!b[i][j]&&a[i][j]>0) d[find(i)]=find(j); if(b[i][j]) { e[++t].l=i; e[t].r=j; e[t].v=a[i][j]; } } sort(e+1,e+t+1); For(i,1,t) { if(find(A)!=find(B)) { if(find(e[i].l)!=find(e[i].r)) { d[find(e[i].l)]=find(e[i].r); ans+=e[i].v; } } else { o(ans); break; } } return 0; }
正解是把未坏的边的权值设成0,坏的边的值不变,跑spfa即可。
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #define inf 2147483647 #define len 10010 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() using namespace std; int n,m,x,y,v,dd,A,B; queue<int>q; int d[110]; bool vis[110],b[110][110]; struct node { int n,v; node *next; }*e[len]; void push(int x,int y,int v) { node *p; p=new node(); p->n=y; p->v=v; if(e[x]==NULL) e[x]=p; else { p->next=e[x]->next; e[x]->next=p; } } void in(int &x) { int y=1; char c=g();x=0; while(c<'0'||c>'9') { if(c=='-') y=-1; c=g(); } while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); x*=y; } void o(int x) { if(x<0) { p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } void spfa(int x) { For(i,1,n) d[i]=inf; d[x]=0; q.push(x); node *p; int t; while(q.size()>0) { t=q.front(); p=e[t]; vis[t]=true; while(p!=NULL) { if(!b[t][p->n]) { if(d[t]<d[p->n]) { d[p->n]=d[t]; if(!vis[p->n]) q.push(p->n); } } else { if(d[t]+p->v<d[p->n]) { d[p->n]=d[t]+p->v; if(!vis[p->n]) q.push(p->n); } } p=p->next; } vis[t]=false; q.pop(); } } int main() { in(n),in(m); For(i,1,m) { in(x),in(y),in(v); push(x,y,v); push(y,x,v); } in(dd); For(i,1,dd) { in(x),in(y); b[x][y]=true; b[y][x]=true; } in(A),in(B); spfa(A); o(d[B]),p(' '); return 0; }