最短路Ⅰ
基础知识懒得写。水题都放在这里的哦。
***集合
评价一个字,水。能评上蓝题说实话有一点侮辱 \(A+B\) \(problem\)。数据范围小,写起简单,还能评上蓝题。这样的题目给我再来一打如何。
#include<cstdio>
#include<cstring>
//#define zczc
using namespace std;
const int N=41;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar(); }
wh*=f;return;
}
inline void check(int &s1,int s2){
if(s1>s2)s1=s2;return;
}
int m,n,q,d[N],a[N][N];
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
int s1,s2;
read(m);read(n);
memset(a,0x3f,sizeof(a));
for(int i=1;i<=n;i++){
read(s1);read(s2);
a[s1][s2]=a[s2][s1]=1;
}
for(int i=1;i<=m;i++){
a[i][i]=0;
for(int j=1;j<=m;j++){
for(int k=1;k<=m;k++){
check(a[j][k],a[j][i]+a[i][k]);
}
}
}
read(q);
while(q--){
read(s1);read(s2);
for(int i=1;i<=m;i++){
if(a[s1][i]+a[i][s2]==a[s1][s2]){
printf("%d ",i);
}
}
putchar('\n');
}
return 0;
}
集合位置
又是集合?
一句话概括,求图的次短路。
一开始做这道题的时候,内心慌得一批,当时写严格次小生成树时写了大半天,而一般来说,树上问题转到图上之后,难度会大幅增加……
不过事实证明,我的担心是多余的。这就是一道模板题,而且特别简单,原因有二,一是因为它是“次小”,而不是“严格次小”;二是因为它数据范围很小,严格次小生成树要求使用 \(O(N logN)\) 的算法,而这道题用 \(O(N^2logN)\) 都能过。那就简单了啊。直接枚举最短路上的每一条边,删去,再跑一遍最短路即可。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
//#define zczc
using namespace std;
const int N=210;
const int M=N*N;
const double Max=1e9;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar(); }
wh*=f;return;
}
int m,n;
struct point{
double x,y;
}a[N];
inline double operator &(point s1,point s2){
double d1=s1.x-s2.x,d2=s1.y-s2.y;
return sqrt(d1*d1+d2*d2);
}
struct edge{
int f,t,next;
double v;
}e[M];
int esum,head[N];
inline void add(int fr,int to,double val){
esum++;
e[esum].t=to;
e[esum].f=fr;
e[esum].v=val;
e[esum].next=head[fr];
head[fr]=esum;
}
double ans=Max,dis[N];
int come[N];
bool vis[N];
struct node{
int num;
double dis;
};
inline bool operator <(node s1,node s2){
return s2.dis<s1.dis;
}
priority_queue<node>q;
void solve(int ch,bool fir){
while(!q.empty())q.pop();
for(int i=1;i<=m;i++)dis[i]=Max;
memset(vis,false,sizeof(vis));
dis[1]=0;q.push((node){1,0});
while(!q.empty()){
node now=q.top();q.pop();
int wh=now.num;double nd=now.dis;
if(vis[wh])continue;vis[wh]=true;
for(int i=head[wh],th;i;i=e[i].next){
if(i==ch)continue;
th=e[i].t;
if(dis[wh]+e[i].v<dis[th]){
if(fir)come[th]=i;
dis[th]=dis[wh]+e[i].v;
q.push((node){th,dis[th]});
}
}
}
if(!fir){
if(ans>dis[m])ans=dis[m];
}
return;
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
int s1,s2;
read(m);read(n);
for(int i=1;i<=m;i++){
cin>>a[i].x>>a[i].y;
}
for(int i=1;i<=n;i++){
read(s1);read(s2);
add(s1,s2,a[s1]&a[s2]);
add(s2,s1,a[s1]&a[s2]);
}
solve(0,true);
int now=m;
while(now){
if(come[now])solve(come[now],false);
else break;
now=e[come[now]].f;
}
if(ans>Max-1)printf("-1");
else printf("%.2f",ans);
return 0;
}
一如既往,万事胜意