http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2929
这个题一方面数据水,另一方面就是思维水,一拿到题就以为考最小生成树。
因为这个题需要求各点间的距离,又因为猪圈的数目最大为600,所以根本就没寻思考Floyd,一方面思维,另一方面是水的后台,因为猪每天去固定的猪圈吃饭,所以求出每个猪到每个猪圈固定的距离便可。
WA(以为已经求出各点间的最短距离,只要猪圈没猪便不会去)
反例
3 4 3
2
3
4
1 2 1
1 3 1
1 4 1
#include#include <string.h> #include #include #define N 1000001 using namespace std; int map[602][602],dis[602],v[602]; int n,m,k,a[401],V; void Floy() {for(int k=1; k<=m; k++){for(int j=1; j<=m; j++){for(int i=1; i<=m; i++){if(map[j][i]>map[j][k]+map[k][i]){map[j][i]=map[j][k]+map[k][i];}}}} } void prim() {memset(v,0,sizeof(v));for(int i=1; i<=m; i++)dis[i]=map[a[1]][i];v[a[1]]=1;int min,k;int sum=0;for(int i=1; i ){min=N;for(int j=1; j<=m; j++){if(v[j]==0&&dis[j]<min){min=dis[j];k=j;}}v[k]=1;//printf("min==%d ",min);sum=sum+min;for(int j=1; j<=m; j++){if(v[j]==0&&dis[j]>map[k][j]){dis[j]=map[k][j];}}}printf("%d ",sum); } int main() {int xx[1211],yy[1211],zz[1211];int sum,sum1;scanf("%d%d%d",&n,&m,&k);for(int i=1; i<=m; i++){for(int j=1; j<=m; j++){map[i][j]=N;map[j][i]=N;}map[i][i]=0;}int b[1211];V=0;memset(b,0,sizeof(b));for(int i=1; i<=n; i++){scanf("%d",&a[i]);b[a[i]]++;}for(int i=1; i<=m; i++){if(b[a[i]])V++;}for(int i=1; i<=k; i++){scanf("%d%d%d",&xx[i],&yy[i],&zz[i]);if(zz[i]<map[xx[i]][yy[i]]){map[xx[i]][yy[i]]=zz[i];map[yy[i]][xx[i]]=zz[i];}}Floy();/*for(int i=1;i<=m;i++){for(int j=1;j<=m;j++){printf("%d ",map[i][j]);}printf(" ");}*/for(int i=1; i<=k; i++){sum=0;sum1=0;for(int j=1; j<=n; j++){if(xx[i]==a[j]) sum++;if(yy[i]==a[j]) sum1++;}if(sum==0){for(int k=1; k<=m; k++){map[xx[i]][k]=N;map[k][xx[i]]=N;}map[xx[i]][xx[i]]=0;}if(sum1==0){for(int k=1; k<=m; k++){map[yy[i]][k]=N;map[k][yy[i]]=N;}map[yy[i]][yy[i]]=0;}if(sum&&sum1){map[xx[i]][yy[i]]=sum*map[xx[i]][yy[i]];map[yy[i]][xx[i]]=sum1*map[yy[i]][xx[i]];}}prim(); } return 0; }
AC的
#include#include <string.h> #include #include #define N 1000001 using namespace std; int n,m,k; int a[351],map[601][601]; void Floy() {for(int k=1; k<=m; k++){for(int i=1; i<=m; i++){for(int j=1; j<=m; j++){if(map[i][j]>map[i][k]+map[k][j]){map[i][j]=map[i][k]+map[k][j];}}}} } int main() {int xx,yy,zz;scanf("%d%d%d",&n,&m,&k);for(int i=1; i<=n; i++)scanf("%d",&a[i]);for(int i=1; i<=m; i++){for(int j=1; j<=m; j++){map[i][j]=N;map[j][i]=N;}map[i][i]=0;}while(k--){scanf("%d%d%d",&xx,&yy,&zz);if(map[xx][yy]>zz){map[xx][yy]=zz;map[yy][xx]=zz;}}Floy();int min=N;int sum;for(int i=1; i<=m; i++){sum=0;for(int j=1; j<=n; j++){sum=sum+map[a[j]][i];}if(min>sum)min=sum;}printf("%d ",min); return 0; }