三维商场,给出点的坐标(200个点),给出点到点的可行路径,1000次询问,要求打出最短路径
能力有限,本来还以为这个题是要用floyd多源最短路径去计算,然后就一直想怎么打印路径的问题…也是之前没有打印最短路径的经验吧…
由于只有200个点,1000次询问,Dijkstra算法复杂度在O(nlogn)(堆优化后)级别,所以直接使用Dijkstra算法打印路径即可
double G[maxn][maxn],dis[maxn];
int pre[maxn];
bool vis[maxn];
int n,m,q;
struct node
{
double x,y,z;
}N[maxn];
double dist(node n1,node n2)
{
return sqrt(pow(n1.x-n2.x,2)+pow(n1.y-n2.y,2)+25*pow(n1.z-n2.z,2));
}
void init()
{
int u,v;
scanf("%d%d",&n,&m);
rep(i,0,maxn) rep(j,0,maxn) G[i][j]=INF; //先把各个结点的距离设为无穷大
rep(i,0,n) scanf("%lf%lf%lf",&N[i].z,&N[i].x,&N[i].y);
char s[10];
rep(i,0,m){
scanf("%d %d %s",&u,&v,s);
if(s[0]=='w'||s[0]=='s')
{
double d=dist(N[u],N[v]);
G[u][v]=min(G[u][v],d); //自己建立边的时候就选择最小的路径建边
G[v][u]=min(G[v][u],d);
}
if(s[0]=='l')
{
G[u][v]=min(G[u][v],1.0);
G[v][u]=min(G[v][u],1.0);
}
if(s[0]=='e')
{
double dis1=1.0,dis2=dist(N[u],N[v])*3.0;
G[u][v]=min(G[u][v],dis1);
G[v][u]=min(G[v][u],dis2);
}
}
}
void dijkstra(int st)
{
rep(i,0,n) dis[i]=INF,vis[i]=false,pre[i]=-1; //初始化
dis[st]=0;
rep(i,0,n){
int u,m=INF;
for(int v=0;vif(!vis[v]&&dis[v]<=m) m=dis[u=v];
vis[u]=1;
for(int v=0;vif(dis[v]>dis[u]+G[u][v]){
dis[v]=dis[u]+G[u][v];
pre[v]=u;
}
}
}
}
void output(int st,int ed)
{
if(pre[ed]!=st) output(st,pre[ed]);
printf("%d ",pre[ed]);
}
int main()
{
int st,ed;
init();
scanf("%d",&q);
rep(i,0,q){
scanf("%d%d",&st,&ed);
if(st==ed){
printf("%d\n",st);
continue;
}
dijkstra(st);
output(st,ed);
printf("%d\n",ed);
}
}
给一些池塘,每个池塘有最大储水量和当前储水量.给出池塘和池塘的联通关系(注意是单向),往x池子里注入y体积的水,询问z池子最后有多少水
BFS,就是注意一下只有当一个池塘的入度为0的时候才能入队列,相当于跟它联通的池子要把水都流完,它的值才是正确的值
struct node
{
double now,maxx;
node(){}
int indegree;
}N[10005];
vector<int> G[10005];
int main()
{
int u,v,n,k,x,y,z;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&N[i].maxx,&N[i].now);
N[i].indegree=0;
G[i].clear();
}
for(int i=0;i"%d%d",&u,&v);
G[u].push_back(v);
//G[v].push_back(u); ///(ㄒoㄒ)/~~这里纠错纠了半天,没看到是单向边...
//N[u].indegree++;
N[v].indegree++;
}
scanf("%d%d%d",&x,&y,&z);
N[x].now+=y;
queue<int> Q;
Q.push(x);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
if(N[u].now<=N[u].maxx) continue;
int numv=G[u].size();
double add=(N[u].now-N[u].maxx)/(double)numv;
N[u].now=N[u].maxx;
for(int i=0;iif(N[v].indegree==0) Q.push(v);
}
}
printf("%.6lf\n",N[z].now);
}