// Floyd多源最短路算法 O(n^3)
#include <iostream>
#include <cmath>
#include <cstring>
#include<algorithm>
using namespace std;
const int N = 101;
int g[N][N];
void Floyd(int n) {
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
for(int k=1; k<=n; k++){
g[j][k]=min(g[j][k],g[j][i]+g[i][k]);
}
}
}
}
int main() {
memset(g, 0x3f, sizeof(g));
for (int i = 0; i < N; i++) {
g[i][i] = 0;
}
int n, m;
int u, v, w;
cin >> n >> m;
for (int i = 0; i < m; i++) {
cin >> u >> v >> w;
g[u][v] = g[v][u] = w;
}
Floyd(n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << g[i][j] << " ";
}
cout << endl;
}
return 0;
}
//朴素的Dijkstra算法(单源最短路 正环)O(n^2)适用于稠密图
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
using namespace std;
const int inf=0x7fffffff;
bool vis[1005];
int d[1005];
struct node{
int v,w;
node(){
}
node(int v2,int w2){
v=v2;
w=w2;
}
};
vector<node> g[1005];
int n,m,s;
int main(){
cin>>n>>m>>s;
for(int i=1; i<=n; i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
memset(d,0x3f,sizeof(d));
d[s]=0;
for(int i=1; i<=n; i++){
int minn=inf;int v=0;
for(int j=1; j<=n; j++){
if(!vis[i]&&d[j]<minn)
{
minn=d[j];
v=j;
}
}
if(minn==inf){
break;
}
vis[v]=true;
for(int j=0; j<g[v].size(); j++){
d[g[v][j].v]=min(d[g[v][j].v],g[v][j].w+d[v]);
}
}
for(int i=1; i<=n; i++){
cout<<d[i]<<" ";
}
return 0;
}
//堆优化的Dijkstra算法(单源最短路 正环)O(m logn)适用于稀疏图
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
using namespace std;
struct node{
int v,w;
node(){
}
node(int v2,int w2){
v=v2;
w=w2;
}
};
set <pair<int,int>> minn;
vector <node> g[1005];
int d[1005];
int main(){
int n,m,s;
cin>>n>>m>>s;
for(int i=1; i<=n; i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
memset(d,0x3f,sizeof(d));
d[s]=0;
minn.insert(make_pair(0,s));
while(minn.size()){
int mind=minn.begin()->first;
int v=minn.begin()->second;
minn.erase(minn.begin());
for(int i=0; i<g[v].size(); i++){
if(d[g[v][i].v]>g[v][i].w+d[v]){
minn.erase(make_pair(d[g[v][i].v],g[v][i].v));
d[g[v][i].v]=d[v]+g[v][i].w;
minn.insert(make_pair(d[g[v][i].v],g[v][i].v));
}
}
}
for(int i=1; i<=n; i++){
cout<<d[i]<<" ";
}
return 0;
}
//SPFA算法(多源最短路 正负环)一般O(m),最坏O(nm)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
using namespace std;
struct node{
int v,w;
node(){
}
node(int vv,int ww){
w=ww;
v=vv;
}
};
vector <node>g[1005];
bool f[1005];
queue<int > q;
int d[1005];
signed main(){
int n,m,s;
cin>>n>>m>>s;
for(int i=1; i<=n ; i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
memset(d,0x3f,sizeof(d));
d[s]=0;
f[s]=1;
q.push(s);
while(!q.empty()){
int now=q.front();
f[now]=0;
q.pop();
for(int i=0; i<g[now].size(); i++){
int x=g[now][i].v;
if(d[x]>d[now]+g[now][i].w){
d[x]=d[now]+g[now][i].w;
if(!f[x]){
f[x]=1;
q.push(x);
}
}
}
}
for(int i=1; i<=n; i++){
cout<<d[i]<<" ";
}
return 0;
}
//SPFA判断负环
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
using namespace std;
struct node{
int v,w;
node(){
}
node(int vv,int ww){
v=vv;
w=ww;
}
};
queue<int> q;
int d[1005],cnt[1005];
vector<node> g[1005];
bool f[1005];
int main(){
int n,m,s,u,v,w;
cin>>n>>m>>s;
for(int i=1; i<=n; i++){
cin>>u>>v>>w;
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
memset(d,0,sizeof(d));
d[s]=0;
f[s]=1;
q.push(s);
cnt[s]++;
while(!q.empty()){
int now=q.front();
q.pop();
f[now]=0;
if(cnt[now]>n){
cout<<"YES";
return 0;
}
for(int i=0; i<g[now].size(); i++){
int x=g[now][i].v;
if(d[x]>d[now]+g[now][i].w){
d[x]=d[now]+g[now][i].w;
if(!f[x]){
q.push(x);
cnt[x]++;
f[x]=1;
}
}
}
}
cout<<"NO";
return 0;
}