1008:n个点m条边(有重边),给定边权和选取该边权的花费,求起点s到终点t的最短距离,以及该最短距离所选取的边权下,的花费,最短距离相同时,选择最小花费的输出。
n=1e3 m=1e4
spfa的一点点变形,当最短距离相同时,松弛一下相同的情况下花费最小的就可以了。其余就是spfa,直接用邻接矩阵写了- -都过了。。。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int inf=999999999;
struct node{
int d;
int p;
}dis[1005],g[1005][1005];
bool inq[1005];
int s,t,n,m;
node spfa(int s,int t,int n)
{
queue<int> q;
for(int i=1;i<=n;i++)
{
dis[i].d=inf;
dis[i].p=inf;
}
memset(inq,0,sizeof(inq));
dis[s].d=0;
dis[s].p=0;
inq[s]=1;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
inq[now]=0;
for(int i=1;i<=n;i++)
{
if(dis[now].d+g[now][i].d<dis[i].d)
{
dis[i].d=dis[now].d+g[now][i].d;
dis[i].p=dis[now].p+g[now][i].p;
if(inq[i]==0)
{
inq[i]=1;
q.push(i);
}
}
if(dis[now].d+g[now][i].d==dis[i].d&&dis[now].p+g[now][i].p<dis[i].p)//如果最短距离相同,更新最小花费
{
dis[i].p=dis[now].p+g[now][i].p;
}
}
}
return dis[t];
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
return 0;
for(int i=1;i<1005;i++)
{
for(int j=1;j<1005;j++)
{
g[i][j].d=inf;
g[i][j].p=inf;
}
}
for(int i=0;i<m;i++)
{
int a,b,c,pp;
scanf("%d%d%d%d",&a,&b,&c,&pp);
if(c<g[a][b].d)//重边处理。
{
g[a][b].d = c;
g[b][a].d = c;
g[a][b].p = pp;
g[b][a].p = pp;
}
}
scanf("%d%d",&s,&t);
spfa(s,t,n);
printf("%d %d\n",dis[t].d,dis[t].p);
}
return 0;
}
1009:求两棵二叉搜索树是不是完全相同的。
思路:数组模拟递归写,感谢BUG教我这个不会数据结构不会DFS的纱布写。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=25;
struct BST{
int arr[maxn];//输入进来的数放进去
int lpos[maxn];//左儿子的位置
int rpos[maxn];//右儿子的位置
int cnt;//树中节点个数
void dfs(int now,int x)
{
if(arr[now]>x)
{
if(lpos[now]!=-1)//如果左儿子这里已经有元素了
{
dfs(lpos[now],x);//就继续向下一层递归
}
else
{
arr[cnt++]=x;//否则记录下当前的元素
lpos[now]=cnt-1;//左儿子的位置就是元素个数-1,初始位置为0
}
}
else
{
if(rpos[now]!=-1)
{
dfs(rpos[now],x);
}
else
{
arr[cnt++]=x;
rpos[now]=cnt-1;
}
}
}
void add_node(int x)
{
if(cnt==0)//存根节点
{
arr[cnt++]=x;
}
dfs(0,x);//从根节点位置出发去递归添加。
}
BST()
{
memset(lpos,-1,sizeof(lpos));
memset(rpos,-1,sizeof(rpos));
cnt=0;
}
BST(const string& s)
{
memset(lpos,-1,sizeof(lpos));
memset(rpos,-1,sizeof(rpos));
cnt=0;
for(int i=0;i<s.size();i++)
{
add_node(s[i]-'0');
}
}
}bsta,bstb;
bool isequ(int nowa,int nowb)
{
if(bsta.arr[nowa]!=bstb.arr[nowb])
{
return false;
}
if(bsta.lpos[nowa]==-1||bstb.lpos[nowb]==-1)//已经递归到最后了
{
if(bsta.lpos[nowa]!=bstb.lpos[nowb])
return false;
}
else if(!isequ(bsta.lpos[nowa],bstb.lpos[nowb]))//还没递归到最后但是所对应的节点编号不同
return false;
if(bsta.rpos[nowa]==-1||bstb.rpos[nowb]==-1)
{
if(bsta.rpos[nowa]!=bstb.rpos[nowb])
return false;
}
else if(!isequ(bsta.rpos[nowa],bstb.rpos[nowb]))
return false;
return true;
}
string a,b;
int main()
{
int n;
while(cin>>n)
{
if(n==0)
return 0;
cin>>a;
bsta=BST(a);
while(n--)
{
cin>>b;
bstb=BST(b);
if(isequ(0,0))
{
puts("YES");
}
else
{
puts("NO");
}
}
}
return 0;
}
完全不知道研究生机试的题目难度到底是啥,迫于生计,只有刷一波九度OJ上的题目了,把基础打好啊,否则感觉要完,太纱布了。。。