农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。
农夫John很狡猾。他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。
农夫John知道每只奶牛都在各自喜欢的牧场呆着(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。
第一行: 三个数:奶牛数N,牧场数P(2<=P<=800),牧场间道路数C(1<=C<=1450).
第二行到第N+1行: 1到N头奶牛所在的牧场号.
第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距(1<=D<=255),当然,连接是双向的.
一行 输出奶牛必须行走的最小的距离和.
3 4 5 2 3 4 1 2 1 1 3 5 2 3 7 2 4 3
3 4 5
样例图形
P2 P1 @--1--@ C1 \ | \ | 5 7 3 \ | \| \ C3 C2 @--5--@ P3 P4
8
{说明: 放在4号牧场最优. }
见描述
自己敲的超时代码,运用结构体+链接表
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define Maxn 2333 5 6 using namespace std; 7 8 int n,p,c,tot,ans=0x7fffffff; 9 int cow[Maxn],headd,tail,js[Maxn]; 10 int num_qwq,head[Maxn],dist[Maxn],que[Maxn]; 11 bool pd[Maxn]; 12 13 struct cower{ 14 int next,to,lenth; 15 }qwq[Maxn]; 16 17 void add(int from,int to,int lenth) 18 { 19 qwq[++num_qwq].next=head[from]; 20 qwq[num_qwq].to=to; 21 qwq[num_qwq].lenth=lenth; 22 head[from]=num_qwq; 23 } 24 25 void sweetbutter(int s) 26 { 27 memset(pd,0,sizeof(pd)); 28 memset(dist,0x7f,sizeof(dist)); 29 int father,son; 30 headd=0,tail=1; 31 dist[s]=0; 32 que[tail]=s; 33 pd[s]=1; 34 while(headd<tail){ 35 father=que[++headd]; 36 pd[father]=0; 37 for(int p=head[father];p!=-1;p=qwq[p].next){ 38 son=qwq[p].to; 39 c=qwq[p].lenth; 40 if(dist[father]+c<dist[son]){ 41 dist[son]=dist[father]+c; 42 if(!pd[son]){ 43 que[++tail]=son; 44 pd[son]=1; 45 } 46 } 47 } 48 } 49 } 50 51 int main() 52 { 53 int a,b,d; 54 scanf("%d %d %d",&n,&p,&c); 55 for(int i=1;i<=n;i++) 56 { 57 scanf("%d",&cow[i]); //记录奶牛出现在各个牧场的次数 58 } 59 memset(head,-1,sizeof(head)); 60 for(int i=1;i<=c;i++) 61 { 62 scanf("%d %d %d",&a,&b,&d); 63 add(a,b,d); 64 add(b,a,d); 65 } 66 for(int i=1;i<=p;i++) 67 { 68 sweetbutter(i); 69 tot=0; 70 for(int j=1;j<=n;j++) tot+=dist[cow[j]]; 71 if(tot<ans) ans=tot; 72 } 73 printf("%d",ans); 74 return 0; 75 }
改进的代码,已ac
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 5 using namespace std; 6 7 int n,p,c,i,j,x,y,t,minn,head,tail,tot,u; 8 9 int a[801][801],b[501],dis[801],num[801],w[801][801],team[1601]; 10 bool exist[801]; 11 int main() 12 { 13 cin>>n>>p>>c; 14 for(i=1;i<=p;i++) 15 { 16 b[i]=0; 17 num[i]=0; 18 for(j=1;j<=p;j++) 19 w[i][j]=0x7fffffff/3; 20 } 21 for(i=1;i<=n;i++)//奶牛编号 22 cin>>b[i]; 23 for(i=1;i<=c;i++) //邻接矩阵存储 24 { 25 cin>>x>>y>>t; 26 w[x][y]=t; 27 a[x][++num[x]]=y; 28 a[y][++num[y]]=x; 29 w[y][x]=w[x][y]; 30 } 31 minn=0x7fffffff/3; 32 for(i=1;i<=p;i++) 33 { 34 for(j=1;j<=p;j++) dis[j]=0x7fffffff/3; 35 memset(team,0,sizeof(team)); //队列数组初始化 36 memset(exist,false,sizeof(exist)); //exist标志初始化 37 dis[i]=0;team[1]=i;head=0;tail=1;exist[i]=true; //起始点入队 38 do 39 { 40 head++; 41 //head=((head-1)%1601)+1; //循环队列处理 42 if(head==1602) head=1; 43 u=team[head]; 44 exist[u]=false; 45 for(j=1;j<=num[u];j++) 46 if (dis[a[u][j]]>dis[u]+w[u][a[u][j]]) 47 { 48 dis[a[u][j]]=dis[u]+w[u][a[u][j]]; 49 if (!exist[a[u][j]]) 50 { 51 tail++; 52 // tail=((tail-1)%1601)+1;//循环处理 53 if(tail==1602) tail=1; 54 team[tail]=a[u][j]; 55 exist[a[u][j]]=true; 56 } 57 } 58 }while(head<tail); 59 tot=0; 60 for(j=1;j<=n;j++) 61 tot+=dis[b[j]]; 62 if (tot<minn) minn=tot; 63 } 64 cout<<minn; 65 return 0; 66 }
原文:http://www.cnblogs.com/zxqxwnngztxx/p/6696191.html