这几天在复习面向对象建模,真是门坑爹的课。。。
复习提纲上概念尼玛就一大堆。。。
还好,复习了一天之后感觉思路清晰了好多
另外物理实验电学也觉得复习的差不多了。。。
于是,,
于是今天又开始练习写代码了。。。
昨天晚上思考了一下感觉自己最短路和最小生成树这边之前练习的时候模版套的太多。。。
于是到目前为止联系了最短路。。。
dijsktra,spfa和floyd。。。
感觉bellman-ford那个不太想用,。。。
好吧。。。
写到这儿先总结一下。。
然后去练习最小生成树。。
嗯。。
说真的
感觉学算法的时候人在真正的投入。。。
文艺点就叫曾经沧海难为水。。。
复习面向对象和物理实验的时候感觉好简单的东西。。。
呵呵呵呵。。。
题解:
poj 3268:http://poj.org/problem?id=3268
/*
正反来一次dijsktra即可
一开始写了floyd超时了
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int n,m,x;
int map1[1005][1005];
int map2[1005][1005];
int dis1[1005];
int dis2[1005];
int dis[1005];
int visit[1005];
void getmap()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map1[i][j]=INF;
map2[i][j]=INF;
}
}
while(m--)
{
int a,b,t;
cin>>a>>b>>t;
map1[a][b]=t;
map2[b][a]=t;
}
}
/*
void floyd()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}
}
}
}
*/
void dijsktra()
{
int k=1;
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++)
{
dis1[i]=map1[x][i];
}
dis1[x]=0;
for(int i=0;i<n;i++)
{
int MIN=INF;
for(int j=1;j<=n;j++)
{
if(!visit[j]&&dis1[j]<MIN)
{
k=j;
MIN=dis1[j];
}
}
if(MIN==INF)
break;
visit[k]=1;
for(int j=1;j<=n;j++)
{
if(!visit[j])
{
dis1[j]=min(dis1[j],dis1[k]+map1[k][j]);
}
}
}
for(int i=1;i<=n;i++)
{
if(dis1[i]==INF)
{
dis1[i]=-1;
}
}
}
void reverse_dijsktra()
{
int k=1;
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++)
{
dis2[i]=map2[x][i];
}
dis2[x]=0;
for(int i=0;i<n;i++)
{
int MIN=INF;
for(int j=1;j<=n;j++)
{
if(!visit[j]&&dis2[j]<MIN)
{
k=j;
MIN=dis2[j];
}
}
if(MIN==INF)
break;
visit[k]=1;
for(int j=1;j<=n;j++)
{
if(!visit[j])
{
dis2[j]=min(dis2[j],dis2[k]+map2[k][j]);
}
}
}
for(int i=1;i<=n;i++)
{
if(dis2[i]==INF)
{
dis2[i]=-1;
}
}
}
int main()
{
while(cin>>n>>m>>x)
{
getmap();
memset(dis1,0,sizeof(dis1));
memset(dis2,0,sizeof(dis2));
dijsktra();
reverse_dijsktra();
// cout<<dis1[1]<<dis2[2];
for(int i=1;i<=n;i++)
{
dis[i]=dis1[i]+dis2[i];
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,dis[i]);
}
cout<<ans<<endl;
}
system("pause");
return 0;
}
hdu 1502: http://poj.org/problem?id=1502
/*
裸dijsktra
注意处理输入
学到了atoi(char s[])可以直接将字符串转换为Int
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int n;
int map[105][105];
int dis[105];
int visit[105];
void getmap()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=i==j?0:INF;
}
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
{
char s[10];
cin>>s;
if(s[0]!='x')
{
map[i][j]=map[j][i]=atoi(s);
}
}
}
}
void dijsktra()
{
int k=1;
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++)
{
dis[i]=map[1][i];
}
for(int i=0;i<n;i++)
{
int MIN=INF;
for(int j=1;j<=n;j++)
{
if(!visit[j]&&dis[j]<MIN)
{
k=j;
MIN=dis[j];
}
}
if(MIN==INF)
break;
visit[k]=1;
for(int j=1;j<=n;j++)
{
if(!visit[j])
{
dis[j]=min(dis[j],dis[k]+map[k][j]);
}
}
}
for(int i=1;i<=n;i++)
{
if(dis[i]==INF)
{
dis[i]=-1;
}
}
}
int main()
{
while(cin>>n)
{
getmap();
dijsktra();
int ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,dis[i]);
}
cout<<ans<<endl;
}
system("pause");
return 0;
}
poj 1125: http://poj.org/problem?id=1125
/*
用了floyd写
关键是理解题意。。
感觉poj的题目明显比hdu难理解。。。。
好吧我太弱了。。
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[105][105];
int sum[105];
int n;
void getmap()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=i==j?0:INF;
}
}
for(int i=1;i<=n;i++)
{
int num;
cin>>num;
while(num--)
{
int e,t;
cin>>e>>t;
map[i][e]=t;
}
}
}
void floyd()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(map[i][k]!=INF&&map[k][j]!=INF)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}
}
}
}
int main()
{
while(cin>>n&&n!=0)
{
getmap();
floyd();
int min=INF,x,max=0;
for(int i=1;i<=n;i++)
{
max=0;
for(int j=1;j<=n;j++)
{
if(i!=j&&max<map[i][j])
{
max=map[i][j];
}
}
if(min>max)
{
min=max;
x=i;
}
}
if(min<INF)
cout<<x<<" "<<min<<endl;
else
cout<<"disjoint"<<endl;
}
system("pause");
return 0;
}
hdu 1231: http://acm.hdu.edu.cn/showproblem.php?pid=1231 这个题乱入了。。。
/*
最大子串和
dp[i]=max{dp[i-1],0}+a[i]
*/
#include<iostream>
using namespace std;
int dp[10005];
int a[10005];
int begin,end,maxsum;
int n;
void MaxSum(int a[],int n)
{
int tempbegin=0;
begin=0;
end=0;
memset(dp,0,sizeof(dp));
dp[0]=maxsum=a[0];
for(int i=1;i<n;i++)
{
if(dp[i-1]<0)
{
dp[i]=a[i];
tempbegin=i;
}
else
{
dp[i]=dp[i-1]+a[i];
}
if(dp[i]>maxsum)
{
maxsum=dp[i];
end=i;
begin=tempbegin;
}
}
}
int main()
{
int T;
while(cin>>n&&n!=0)
{
for(int i=0;i<n;i++)
{
cin>>a[i];
}
MaxSum(a,n);
if(maxsum<0)
{
cout<<"0 "<<a[0]<<" "<<a[n-1]<<endl;
}
else
{
cout<<maxsum<<" "<<a[begin]<<" "<<a[end]<<endl;
}
}
system("pause");
return 0;
}
/*
手敲dijsktra模版,
1A
越来越熟练了
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[105][105];
int visit[105];
int dis[105];
int n,m;
void getmap()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=i==j?0:INF;
}
}
while(m--)
{
int s,e,l;
cin>>s>>e>>l;
map[s][e]=map[e][s]=l;
}
}
void dijsktra()
{
int k=1;
memset(visit,0,sizeof(visit));
memset(dis,0,sizeof(dis));
for(int i=1;i<=n;i++)
{
dis[i]=map[1][i];
}
for(int i=0;i<n;i++)
{
int MIN=INF;
for(int j=1;j<=n;j++)
{
if(!visit[j]&&dis[j]<MIN)
{
MIN=dis[j];
k=j;
}
}
if(MIN==INF)
break;
visit[k]=1;
for(int j=1;j<=n;j++)
{
if(!visit[j])
{
dis[j]=min(dis[j],dis[k]+map[k][j]);
}
}
}
cout<<dis[n]<<endl;
}
int main()
{
while(cin>>n>>m,n!=0&&m!=0)
{
getmap();
dijsktra();
}
system("pause");
return 0;
}
hdu 2066: http://acm.hdu.edu.cn/showproblem.php?pid=2066
/*
dijsktra,
求从s个点出发到d个点中的最短路径
两层for循环就好了~
1A
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[1005][1005];
int visit[1005];
int dis[1005];
int start[1005];
int end[1005];
int s,t,d,n;
void getmap()
{
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=1000;j++)
{
map[i][j]=i==j?0:INF;
}
}
n=0;
while(t--)
{
int a,b,l;
cin>>a>>b>>l;
map[a][b]=map[b][a]=min(l,map[a][b]);
n=max(n,max(a,b));
}
for(int i=1;i<=s;i++)
{
cin>>start[i];
}
for(int i=1;i<=d;i++)
{
cin>>end[i];
}
}
void dijsktra(int s)
{
int k=1;
memset(visit,0,sizeof(visit));
memset(dis,0,sizeof(dis));
for(int i=1;i<=n;i++)
{
dis[i]=map[s][i];
}
for(int i=0;i<n;i++)
{
int MIN=INF;
for(int j=1;j<=n;j++)
{
if(!visit[j]&&dis[j]<MIN)
{
MIN=dis[j];
k=j;
}
}
if(MIN==INF)
break;
visit[k]=1;
for(int j=1;j<=n;j++)
{
if(!visit[j])
{
dis[j]=min(dis[j],dis[k]+map[k][j]);
}
}
}
}
int main()
{
while(cin>>t>>s>>d)
{
getmap();
int ans=INF;
for(int i=1;i<=s;i++)
{
dijsktra(start[i]);
int MIN=INF;
for(int j=1;j<=d;j++)
{
MIN=min(dis[end[j]],MIN);
}
ans=min(ans,MIN);
}
cout<<ans<<endl;
}
system("pause");
return 0;
}
hdu 1874: http://acm.hdu.edu.cn/showproblem.php?pid=1874
/*
尝试用spfa算法
1A~~
*/
#include<iostream>
#include<queue>
#include<algorithm>
#define INF 0x3f3f3f
using namespace std;
int map[205][205];
int visit[205];
int dis[205];
int n,m;
int start,end;
void getmap()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
map[i][j]=map[j][i]=i==j?0:INF;
}
}
while(m--)
{
int s,e,l;
cin>>s>>e>>l;
map[s][e]=map[e][s]=min(map[s][e],l);
}
cin>>start>>end;
}
queue<int>q;
void spfa()
{
while(!q.empty())
{
q.pop();
}
memset(visit,0,sizeof(visit));
memset(dis,INF,sizeof(dis));
dis[start]=0;
q.push(start);
visit[start]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
visit[x]=0;
for(int i=0;i<n;i++)
{
if(dis[i]>dis[x]+map[x][i])
{
dis[i]=dis[x]+map[x][i];
if(!visit[i])
{
q.push(i);
visit[i]=1;
}
}
}
}
if(dis[end]==INF)
{
cout<<"-1"<<endl;
}
else
{
cout<<dis[end]<<endl;
}
}
int main()
{
while(cin>>n>>m)
{
getmap();
spfa();
}
system("pause");
return 0;
}
hdu 2680: http://acm.hdu.edu.cn/showproblem.php?pid=2680
/*
反向变成单源最短路
练习spfa
少写一次visit置0wa一次
不错~
*/
#include<iostream>
#include<algorithm>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
int map[1005][1005];
int visit[1005];
int dis[1005];
int end[1005];
int n,m,s,w;
void getmap()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=i==j?0:INF;
}
}
while(m--)
{
int s,e,l;
cin>>s>>e>>l;
map[e][s]=min(map[e][s],l);
}
cin>>w;
for(int i=1;i<=w;i++)
{
cin>>end[i];
}
}
queue<int>q;
void spfa()
{
while(!q.empty())
{
q.pop();
}
memset(visit,0,sizeof(visit));
memset(dis,INF,sizeof(dis));
dis[s]=0;
q.push(s);
visit[s]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
visit[x]=0;
for(int i=1;i<=n;i++)
{
if(dis[i]>dis[x]+map[x][i])
{
dis[i]=dis[x]+map[x][i];
if(!visit[i])
{
q.push(i);
visit[i]=1;
}
}
}
}
}
int main()
{
while(cin>>n>>m>>s)
{
getmap();
spfa();
int ans=INF;
for(int i=1;i<=w;i++)
{
ans=min(ans,dis[end[i]]);
}
if(ans==INF)
{
cout<<"-1"<<endl;
}
else
{
cout<<ans<<endl;
}
}
system("pause");
return 0;
}