本题运用spfa来做,我用了vector优化,和数组来优化的两种方式,没有用bellman_ford来做了,另外注意结构体和vector的定义要用大的那个数组来
spfa,vector优化型:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
using namespace std;
const int maxn = 100005;
const int maxm = 205;
const int INF = 0xfffffff;
int dis[maxn],vis[maxn],head[maxn],a[maxn],count[maxn];
struct Edge{
int b,c;
Edge(int y,int z):b(y),c(z*z*z){}
};
int n;
vector<Edge> edge[maxn];
void init()
{
for(int i=1;i<=n;i++)
edge[i].clear();
}
void spfa(int x)
{
stack<int> s;
s.push(x);vis[x]=1;
dis[x]=0;
while(!s.empty())
{
int u=s.top();s.pop();
vis[u]=0;count[u]++;
for(int i=0;i<edge[u].size();i++)
{
Edge p=edge[u][i];
int v=p.b,w=p.c;
if((dis[v]>dis[u]+w)){
dis[v]=dis[u]+w;
if(!vis[v]&&count[v]<=n)
{
vis[v]=1;
//count[v]++;
s.push(v);
}
}
}
}
}
int main()
{
int t,m,q;
int x,y,cnt=0;
//freopen("O.txt","r",stdin);
scanf("%d",&t);
// cout<<t<<endl;
while(t--)
{
printf("Case %d:\n",++cnt);
init();
scanf("%d",&n);
//cout<<n<<endl;
for(int i=1;i<=n;i++)
{
vis[i]=0;
dis[i]=INF;
head[i]=-1;
count[i]=0;
scanf("%d",&a[i]);
//cout<<a[i]<<endl;
}
scanf("%d",&m);
//cout<<m<<endl;
for(int i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
int c=a[y]-a[x];
edge[x].push_back(Edge(y,c));
}
scanf("%d",&q);
spfa(1);
//cout<<q<<endl;
while(q--)
{
scanf("%d",&y);
if(dis[y]<3||dis[y]==INF||count[y]>n)
printf("?\n");
else
printf("%d\n",dis[y]);
}
}
return 0;
}
spfa,head型:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 100005;
const int maxm = 205;
const int INF = 0xfffffff;
int dis[maxn],vis[maxn],head[maxn],a[maxn],count[maxn];
struct node{
int a,b,c,next;
}p[maxn];
int n;
void spfa(int x)
{
stack<int> s;
s.push(x);vis[x]=1;
dis[x]=0;
while(!s.empty())
{
int u=s.top();s.pop();
vis[u]=0;count[u]++;
for(int i=head[u];i!=-1;i=p[i].next)
{
int v=p[i].b,w=p[i].c;
if((dis[v]>dis[u]+w)){
dis[v]=dis[u]+w;
if(!vis[v]&&count[v]<=n)
{
vis[v]=1;
//count[v]++;
s.push(v);
}
}
}
}
}
void add(int a,int b,int c,int len)
{
p[len].a=a;
p[len].b=b;
p[len].c=c*c*c;
p[len].next=head[a];
head[a]=len;
}
int main()
{
int t,m,q;
int x,y,cnt=0;
//freopen("O.txt","r",stdin);
scanf("%d",&t);
// cout<<t<<endl;
while(t--)
{
printf("Case %d:\n",++cnt);
//init();
scanf("%d",&n);
//cout<<n<<endl;
for(int i=1;i<=n;i++)
{
vis[i]=0;
dis[i]=INF;
head[i]=-1;
count[i]=0;
scanf("%d",&a[i]);
//cout<<a[i]<<endl;
}
scanf("%d",&m);
//cout<<m<<endl;
for(int i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
int c=a[y]-a[x];
add(x,y,c,i-1);
}
scanf("%d",&q);
spfa(1);
//cout<<q<<endl;
while(q--)
{
scanf("%d",&y);
if(dis[y]<3||dis[y]==INF||count[y]>n)
printf("?\n");
else
printf("%d\n",dis[y]);
}
}
return 0;
}