Description
已给定一个 N 个点 M条边的有向图,点编号为 1到N,第i 条边为(ui,vi) ,
权值为wi。你可以进行一次操作,使得任意一条边的权值变成任意非负整数。要
求进行尽量少的操作次数,使得点 1到点N 的最短路径长度变成c。
题目保证,c小于在未进行任何操作之前的原图中 1到N 的最短路长度。
Input
输入文件tweak.in 第一行三个整数,N,M和c
接下来M行,每行一条边的信息 ui,vi和wi,第i 行的表述第i 条边的信息。
保证不会有自环存在,对于不同的 i 和j, (ui,vi)不同于(uj,vj) 。
Output
输出文件 tweak.out 一行一个整数,要进行最少多少次操作才能使得最短路
长度变为c。
Sample Input
3 3 3
1 2 3
2 3 3
1 3 8
Sample Output
1
Data Constraint
Hint
将边 1,3的权值修改为 2就可以了。
N≤100
M≤1000
0≤c≤100000
0≤wi≤10000
30%数据满足M≤20
50%的数据满足 M≤70
.
.
.
.
.
.
程序(50分):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,c,f[101][101][101],dis[101][101];
int main()
{
memset(f,63,sizeof(f));
memset(dis,63,sizeof(dis));
scanf("%d%d%d",&n,&m,&c);
for (int i=1;i<=n;i++)
{
f[i][i][0]=0;
dis[i][i]=0;
}
for (int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
dis[u][v]=w;
f[u][v][0]=min(f[u][v][0],w);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
{
f[i][j][0]=min(f[i][j][0],f[i][k][0]+f[k][j][0]);
for (int l=1;l<=n;l++)
{
if (dis[k][j]!=0X3f3f3f3f) f[i][j][l]=min(f[i][j][l],f[i][k][l-1]);
f[i][j][l]=min(f[i][j][l],f[i][k][l]+f[k][j][0]);
}
}
int ans;
for (int i=0;i<=n;i++)
if (f[1][n][i]<=c)
{
ans=i;
break;
}
printf("%d",ans);
return 0;
}
.
.
.
.
.
程序(100分):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct edge
{
int next,to,w;
}e[9999924];
queue<int>q;
int n,m,u[1004],v[1004],w[1004],d[502004],head[502004],ne,c,inf=0X3f3f3f;
bool f[502004];
void add(int u,int v,int w)
{
e[++ne].to=v;e[ne].w=w;e[ne].next=head[u];head[u]=ne;
}
void spfa()
{
memset(d,inf,sizeof(d));
memset(f,false,sizeof(f));
q.push(1);
d[1]=0;
f[1]=false;
while (!q.empty())
{
int u=q.front();
q.pop();
f[u]=false;
for (int i=head[u];i;i=e[i].next)
if (d[u]+e[i].w<d[e[i].to])
{
d[e[i].to]=d[u]+e[i].w;
q.push(e[i].to);
f[e[i].to]=true;
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&c);
for (int i=1;i<=m;i++)
scanf("%d%d%d",&u[i],&v[i],&w[i]);
for (int t=0;t<=m;t++)
for (int i=1;i<=m;i++)
{
add(u[i]+t*n,v[i]+t*n,w[i]);
add(u[i]+t*n,v[i]+(t+1)*n,0);
}
spfa();
for (int i=0;i<=m;i++)
if (d[i*n+n]<=c)
{
printf("%d",i);
break;
}
return 0;
}