最短路 2Time Limit: 6000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 687 Accepted Submission(s): 176 Problem Description 小 A 是社团里的工具人,有一天他的朋友给了他一个 n 个点,m 条边的正权连通无向图,要他计算所有点两两之间的最短路。
Input 第一行一个正整数 T(T≤30) 表示数据组数
Output 输出 T 行,第 i 行一个非负整数表示第 i 组数据的答案
Sample Input 1 4 4 1 2 1 2 3 1 3 4 1 4 1 1
Sample Output 6
Source
Recommend liuyiding
|
每次在松弛的时候记录中断点。
当距离小时,会更新中断点,或者是当距离=原先保存的最小值时,看max(a[s][x],x)是否小于a[s][to],更新一下。
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
//priority_queue<ll,vector<ll>,less<ll> >q;
ll dx[]= {-1,1,0,0,-1,-1,1,1};
ll dy[]= {0,0,-1,1,-1,1,1,-1};
const ll maxn = 2000+66;
const ll mod=998244353;
const ll inf=99999999999;
ll n,m;
ll mas[maxn][maxn];
struct edge
{
ll to;
ll next;
ll v;
};
struct Dij
{
edge edge[maxn*2];
ll cnt,head[maxn*2],n;
ll dis[maxn];
void init(ll nn)
{
n=nn;
cnt=0;
for(ll i=0; i<=n; i++)
{
head[i]=0;
}
}
void add(ll u,ll v,ll w)
{
cnt++;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
edge[cnt].v=w;
}
void ans(ll s)
{
priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>> >q;
while(q.size())
q.pop();
ll i,now;
for (i=1; i<=n; i++)
dis[i]=inf;
dis[s]=0;
q.push(make_pair(0,s));
//cout<<s<<"++"<<endl;
while (!q.empty())
{
now=q.top().second;
q.pop();
for (i=head[now]; i; i=edge[i].next)
{
ll to=edge[i].to;
//cout<<to<<"------"<<endl;
if (dis[now]+edge[i].v<dis[edge[i].to]||dis[now]+edge[i].v==dis[edge[i].to]&&max(mas[s][now],now)<mas[s][to])
{
ll tmp=max(mas[s][now],now);
//cout<<tmp<<"--"<<endl;
if(tmp!=s&&tmp!=to)
{
mas[s][to]=tmp;
//mas[to][s]=tmp;
//cout<<tmp<<"--"<<s<<" "<<to<<endl;
}
dis[edge[i].to]=dis[now]+edge[i].v;
q.push(make_pair(dis[edge[i].to],edge[i].to));
}
}
}
}
void solve()
{
for(ll i=1; i<=n; i++)
{
ans(i);
//cout<<mas[1][2]<<"!"<<endl;
}
}
} D;
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld",&n,&m);
D.init(n);
for(ll i=1; i<=n+10; i++)
{
for(ll j=1; j<=n+10; j++)
{
mas[i][j]=0;
}
}
for(ll i=1; i<=m; i++)
{
ll u,v;
ll w;
scanf("%lld %lld %lld",&u,&v,&w);
D.add(u,v,w);
D.add(v,u,w);
}
D.solve();
ll num=0;
//cout<<mas[1][2]<<"!"<<endl;
for(ll i=1; i<=n; i++)
{
for(ll j=i+1; j<=n; j++)
{
num+=mas[i][j];
num%=mod;
}
}
printf("%I64d\n",(2*num)%mod);
}
}