做了一题,开心,冒一下泡:
题目大意:有一些草原(1,……,p个),告诉你n个奶牛的在哪个草原,Famer John 会在其中一个草原放一块糖,
让所有的奶牛去舔(提高奶的质量^-^),要求的就是把糖放在哪个草原使所有的奶牛到那的路程和最短。
(当然奶牛都是拣最短的路走)。
第一种超时思路 :Floyd算法求出任意两个草原间的距离,枚举所有草原,取所有奶牛所在的草原到该草原和的最大值。
很不幸TLE了,O(800^3);
第二种超时思路:用Dijkstra+priority_queue(优先级队列),枚举所有草原算单源最短路径,如果不优化还是O(800^3)
用priority_queue还是TLE了,Dijkstra找最近的的时候用优先级队列很快,O(1),调整O(log n),可能是用的不够好。
貌似有人用这种方法做出来。不知道用邻接表行不行。
第三种思路:就是SPFA算法(Shortest Path Fast Algorithm):
用邻接表,枚举所有草原,用SPFA算单源最短路径,SPFA算法要用到队列,一个标记数组用于判断是否在队列中,
d[]数组,存放i到所有点的距离,初始值都为MAX,d[i]=0。
枚举的草原i先入队。如果队列非空就开始迭代,取队首元素x并弹出它,对于所有与x相邻的(邻接表的好处体现了)u,
如果d[u]>d[x]+len(x,u)(x到u的距离)d[u]=d[x]+len(x,u),这样d[u]进行更新了,d[u]可能会继续更新别的点,
如果u不在队列的话,就把u放在队列中。一直迭代下去,直到队列为空(就是说没有在更新了);
1# TLE
USER: tian tianbing [tbbd4261]
TASK: butter
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.000 secs, 5544 KB]
Test 2: TEST OK [0.000 secs, 5544 KB]
Test 3: TEST OK [0.011 secs, 5544 KB]
Test 4: TEST OK [0.022 secs, 5544 KB]
Test 5: TEST OK [0.022 secs, 5544 KB]
Test 6: TEST OK [0.054 secs, 5544 KB]
Test 7: TEST OK [0.410 secs, 5544 KB]
> Run 8: Execution error: Your program (`butter') used more than the
allotted runtime of 1 seconds (it ended or was stopped at 1.339
seconds) when presented with test case 8. It used 5544 KB of
memory.
|
想用Foloyd()求最短路径,超时了。
/*
ID:tbbd4261
PROG:butter
LANG:C++
*/
#include<fstream>
using namespace std;
const int MAX=805;
const int INF=0x0fffffff;
int adj[MAX][MAX]={0};
int location[505];
int n,p,c;
ifstream fin("butter.in");
ofstream fout("butter.out");
void init()
{
int i,j;
for(i=1; i<=p; i++)
for(j=1; j<=p; j++)
adj[i][j]=INF;
for(i=1; i<=p; i++)
adj[i][i]=0;
}
void Floyd()
{
int i,j,k;
for(k=1; k<=p; k++)
for(i=1; i<=p; i++)
for(j=1; j<=p; j++)
{
if(i==j)continue;
if(adj[i][j]>adj[i][k]+adj[k][j])
adj[i][j]=adj[i][k]+adj[k][j];
}
}
void print()
{
int i,j;
for(i=1; i<=p; i++,fout<<endl)
for(j=1; j<=p; j++)
fout<<adj[i][j]<<' ';
}
int main()
{
fin>>n>>p>>c;
init();
for(int i=1; i<=n; i++ )
fin>>location[i];
for(int i=1,len,s,t; i<=c; i++)
{
fin>>s>>t>>len;
adj[t][s]=adj[s][t]=len;
}
Floyd();
int minSum=INF,sum;
for(int i=1; i<=p; i++)
{
bool f=true;
sum=0;
for(int j=1; j<=n; j++)
{
if(adj[i][location[j]]!=INF)
{
sum+=adj[i][location[j]];
}
else f=false;
}
if(f==true&&sum<minSum)minSum=sum;
}
fout<<minSum<<endl;
return 0;
}
2,TLE
USER: tian tianbing [tbbd4261]
TASK: butter
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.000 secs, 5552 KB]
Test 2: TEST OK [0.022 secs, 5552 KB]
Test 3: TEST OK [0.011 secs, 5552 KB]
Test 4: TEST OK [0.011 secs, 5552 KB]
Test 5: TEST OK [0.032 secs, 5552 KB]
Test 6: TEST OK [0.097 secs, 5552 KB]
Test 7: TEST OK [0.637 secs, 5552 KB]
> Run 8: Execution error: Your program (`butter') used more than the
allotted runtime of 1 seconds (it ended or was stopped at 1.674
seconds) when presented with test case 8. It used 5552 KB of
memory.
|
改用Dijkstra+priority_queue(STL)更慢了…………
/*
ID:tbbd4261
PROG:butter
LANG:C++
*/
#include<fstream>
#include<iostream>
#include<queue>
#include<functional>
#include<cstring>
using namespace std;
const int MAX=805;
const int INF=0x0fffffff;
int n,p,c;
int location[505]={0};
int adj[MAX][MAX]={0};
ifstream fin("butter.in");
ofstream fout("butter.out");
typedef pair<int ,int > type;
int d[MAX];
bool done[MAX];
int dijkstra(int t)
{
memset(done,0,sizeof done);
for(int i=1; i<=p; i++)
d[i]=INF;
d[t]=0;
priority_queue<int ,vector<type > ,greater<type> >q;
q.push(make_pair(d[t],t));
type temp;
while(!q.empty())
{
temp=q.top(); q.pop();
int x=temp.second;
if(done[x])continue;
done[x]=true;
//fout<<x<<' '<<d[x]<<endl;
for(int j=1; j<=p; j++)
{
if(d[j]>d[x]+adj[x][j])
{
d[j]=d[x]+adj[x][j];
q.push(make_pair(d[j],j));
}
}
}
int ans=0;
for(int i=1; i<=n; i++)
if(d[location[i]]==INF)return -1;
else ans+=d[location[i]];
return ans;
}
void init()
{
int i,j;
for(i=1; i<=p; i++)
for(j=1; j<=p; j++)
adj[i][j]=(i==j?0:INF);
}
void print()
{
fout<<"print location: "<<endl;
for(int i=1; i<=n; i++)
fout<<location[i]<<' ';
fout<<endl;
fout<<"print adj: "<<endl;
for(int i=1; i<=p; i++,fout<<endl)
for(int j=1; j<=p; j++)
fout<<adj[i][j]<<' ';
fout<<endl;
}
int main()
{
fin>>n>>p>>c;
init();
for(int i=1; i<=n; i++)
fin>>location[i];
for(int i=1,s,t,len; i<=c; i++)
{
fin>>s>>t>>len;
adj[s][t]=adj[t][s]=len;
}
//print();
int min=INF;
for(int i=1,tt; i<=p; i++)
{
tt= dijkstra(i);
//system("pause");
if(tt!=-1&&tt<min)
min=tt;
}
fout<<min<<endl;
//system("pause");
return 0;
}
USER: tian tianbing [tbbd4261]
TASK: butter
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.011 secs, 8084 KB]
Test 2: TEST OK [0.000 secs, 8084 KB]
Test 3: TEST OK [0.011 secs, 8084 KB]
Test 4: TEST OK [0.022 secs, 8084 KB]
Test 5: TEST OK [0.000 secs, 8084 KB]
Test 6: TEST OK [0.011 secs, 8084 KB]
Test 7: TEST OK [0.054 secs, 8084 KB]
Test 8: TEST OK [0.108 secs, 8084 KB]
Test 9: TEST OK [0.162 secs, 8084 KB]
Test 10: TEST OK [0.173 secs, 8084 KB]
All tests OK.
Your program ('butter') produced all correct answers! This is your
submission #5 for this problem. Congratulations!
3,A了!
千呼万唤始出来,终于A了,而且速度挺快!!!
传说中的SPFA算法:
/*
ID:tbbd4261
PROG:butter
LANG:C++
*/
#include<fstream>
#include<cstring>
#include<queue>
using namespace std;
const int MAX=805;
const int INF=0x0fffffff;
ifstream fin("butter.in");
ofstream fout("butter.out");
struct node{
int end,len;
};
int cnt[MAX]={0},location[505]={0},n,p,c;
node adj[MAX][MAX];
bool in[MAX]={0};
int d[MAX];
int SPFA(int i)
{
memset(in,0,sizeof in);
for(int k=1; k<=p; k++)d[k]=INF;
queue<int> Q;
Q.push(i);
in[i]=true;
d[i]=0;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
in[x]=false;
for(int j=0; j<cnt[x]; j++)
if(d[x]+adj[x][j].len < d[ adj[x][j].end ])
{
d[adj[x][j].end]=d[x]+adj[x][j].len;
if(!in[adj[x][j].end])
{
Q.push(adj[x][j].end);
in[adj[x][j].end ]=true;
}
}
}
int ans=0;
for(int j=1; j<=n; j++)
{
if(d[location[j]]==INF)return -1;
else ans+=d[location[j]];
}
return ans;
}
void print()
{
int i,j;
for(i=1; i<=p ; i++)
for(j=0; j<cnt[i]; j++)
{
fout<<i<<' '<<adj[i][j].end<<' '<<adj[i][j].len<<endl;
}
}
int main()
{
memset(cnt,0,sizeof cnt);
fin>>n>>p>>c;
for(int i=1; i<=n; i++)
fin>>location[i];
for(int i=1,s,t,value; i<=c; i++)
{
fin>>s>>t>>value;
adj[s][cnt[s]].end=t; adj[s][cnt[s]].len=value; cnt[s]++;
adj[t][cnt[t]].end=s; adj[t][cnt[t]].len=value; cnt[t]++;
}
int tt,min=INF;
for(int i=1; i<=p; i++)
{
tt=SPFA(i);
if(tt<min&&tt!=-1) min=tt;
}
fout<<min<<endl;
//system("pause");
return 0;
}