题面如图:
这道题 爽的一批
我至今无法知道某同学是如何猜出满分结论的而且该同学混合表达式那道题的动规竟然会想不到??????????
……讲题的时候老师叫我们多学习该同学的刻苦钻研精神,在考场要像这样才能拿到分数。。。
ps:考场又不给我手机和网络,让我怎么在百度里刻苦钻研???
——————————一点点废话和牢骚———————————————
按该同学的无敌言论,他花了一个小时刻苦的钻研的树上前缀和结论,我花了两分钟就想出来,哎,可惜他花了一个半小时钻研出来的致命优化方案,我没那么“聪明”,钻研不出来。
这道题可以广搜先维护一遍spfa,然后暴力查询,时间复杂度大概是O(nm),这个其实我第一眼想到的是深搜,每读入一个两个点之间的关系,互相对对方的连接到的所有点进行扩展,譬如说
1—–2——3——4——5
我们要求1到5的全部点对距离,是不是12加四遍,23加三遍,34加二遍,45加一遍,O(n2)造图,O(1)查询,因为m很大,所以深搜要比广搜优,大概八千做的下?
这个是错误的代码,但大概是这样的,考试的时候我系数o的更新反了。。。懒得改了。。。。
#include <bits/stdc++.h>
using namespace std;
const int maxn=10010;
struct node
{
int v,w;
node(int x,int y):v(x),w(y){}
};
vector <node> g[maxn];
inline int read()
{
int X=0,w=0; char c=0;
while(c<'0'||c>'9') {w|=c=='-';c=getchar();}
while(c>='0'&&c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar();
return w?-X:X;
}
int dist[5010][5010],vis[5010],sumdist[5010][5010];
void dfs(int u,int v,int dis,int o)
{
for (int i=0; i<g[v].size(); i++)
{
int x=g[v][i].v,y=g[v][i].w;
if (vis[x]==false)
{
vis[x]=true;
dist[u][x]=dist[u][v]+y;
sumdist[u][x]+=dis;
dfs(u,x,dis+=o*y,o++);
vis[x]=false;
}
}
}
int main()
{
int n,m;
n=read(); m=read();
for (int i=1; i<=m; i++)
{
int x,u,v,w;
x=read();
if (x==1)
{
u=read(),v=read(),w=read();
g[u].push_back(node(v,w));
dist[u][v]=w;
sumdist[u][v]=w;
dfs(u,v,0,1);
g[v].push_back(node(u,w));
dist[v][u]=w;
sumdist[v][u]=w;
dfs(v,u,0,1);
}
if (x==2)
{
int ans;
u=read(); v=read();
if (sumdist[max(u,v)][min(u,v)]==0) cout<<"-1"<<"\n";
else cout<<sumdist[max(u,v)][min(u,v)]<<"\n";
//cout<<ans<<"\n";
}
}
// for (int i=1; i<=n; i++)
// {
// for (int j=1; j<=n; j++)
// cout<<dist[i][j]<<' ';
// cout<<endl;
// }
// cout<<endl;
// for (int i=1; i<=n; i++)
// {
// for (int j=1; j<=n; j++)
// cout<<sumdist[i][j]<<' ';
// cout<<endl;
// }
}
正确解法:
给你们讲个笑话,某同学号称自己刻苦钻研了两个半小时推出了结论,并花了半个小时打了大概两三白行的代码。呵呵呵呵呵呵呵呵呵呵呵
……正解有点没懂等下