以下用数组而非图的形式对路径进行了定义。
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Route2 {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(),m = scanner.nextInt();
//System.out.println(m);
long[][] edges=new long[n+1][n+1];
//ArrayList<Edge> directedEdges = new ArrayList<>();
//for(int i = 0;i < m;i ++){
// directedEdges.add(new Edge(scanner.nextInt()==0,scanner.nextInt(),scanner.nextInt(),scanner.nextInt()));
//}
int[][] tag=new int[n+1][n+1];
for(int i=0;i<n+1;i++)
{
Arrays.fill(edges[i], 10*10*10*10*10*10);
}
for(int j=0;j<=n;j++)
edges[j][j]=0;//这里其实做不做都可以 写32767也行
for(int i=0;i<m;i++)
{
int a1=scanner.nextInt();//System.out.println(a1);//指示为大路(0)还是小路(1)
int a2=scanner.nextInt();//System.out.println(a2);//from
int a3=scanner.nextInt();//System.out.println(a3);//to
long a4=scanner.nextInt();//System.out.println(a4);//weight
tag[a2][a3]=a1; tag[a3][a2]=a1;
edges[a2][a3]=a4;edges[a3][a2]=a4;
}
//for(int i=1;i<n+1;i++)
// for(int j=1;j<n+1;j++)
// System.out.println(tag[i][j]);
long[] dist=new long[n+1];//到待定点的距离
long[] lianxi=new long[n+1];//已连续走了多少路
int[] visited=new int[n+1];//该点是否已被访问
Arrays.fill(dist, 10*10*10*10*10*10);
dist[1]=0;
//for(int i=1;i<=n;i++)
// System.out.println(dist[i]);
//System.out.println("duanduan");
Arrays.fill(visited, 0);
//for(int i=0;i<n+1;i++)
// System.out.println(visited[i]);
Arrays.fill(lianxi, 0);
//如果距离初始化的话就可以按照课本来
//否则按照下面步骤
for(int j=0;j<n;j++)
{
int v=-1;
for(int k=1;k<=n;k++)
{
if(visited[k]==0)
{
if(v==-1||(dist[k]<dist[v]))
v=k;
}
}
if(v==-1)//有没有都可以 前面for循环已经限定了次数
break;
visited[v]=1;//将点拿入
for(int mm=1;mm<=n;mm++)
{//大道
if(visited[mm]==0) {//这句话其实用不用都行 因为不这样也就是多搜索几遍而已
if(tag[v][mm]==0)
{
if(dist[mm]>dist[v]+edges[v][mm])
{
dist[mm]=dist[v]+edges[v][mm];
lianxi[mm]=0;
}
}//小道
else if(tag[v][mm]==1)
{
if(lianxi[v]==0)
{
long temp=dist[v]+edges[v][mm]*edges[v][mm];
if(temp<dist[mm])
{
dist[mm]=temp;
lianxi[mm]=edges[v][mm];
//System.out.println(temp);
}
}
else
{
long temp=dist[v]-lianxi[v]*lianxi[v]+(lianxi[v]+edges[v][mm])*(lianxi[v]+edges[v][mm]);
if(temp<dist[mm])
{
dist[mm]=temp;
lianxi[mm]=edges[v][mm]+lianxi[v];
}
}
}
}
}
}
System.out.println(dist[n]);
}
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(),m = scanner.nextInt();
//System.out.println(m);
long[][] edges=new long[n+1][n+1];
//ArrayList<Edge> directedEdges = new ArrayList<>();
//for(int i = 0;i < m;i ++){
// directedEdges.add(new Edge(scanner.nextInt()==0,scanner.nextInt(),scanner.nextInt(),scanner.nextInt()));
//}
int[][] tag=new int[n+1][n+1];
for(int i=0;i<n+1;i++)
{
Arrays.fill(edges[i], 10*10*10*10*10*10);
}
for(int j=0;j<=n;j++)
edges[j][j]=0;//这里其实做不做都可以 写32767也行
for(int i=0;i<m;i++)
{
int a1=scanner.nextInt();//System.out.println(a1);//指示为大路(0)还是小路(1)
int a2=scanner.nextInt();//System.out.println(a2);//from
int a3=scanner.nextInt();//System.out.println(a3);//to
long a4=scanner.nextInt();//System.out.println(a4);//weight
tag[a2][a3]=a1; tag[a3][a2]=a1;
edges[a2][a3]=a4;edges[a3][a2]=a4;
}
//for(int i=1;i<n+1;i++)
// for(int j=1;j<n+1;j++)
// System.out.println(tag[i][j]);
long[] dist=new long[n+1];//到待定点的距离
long[] lianxi=new long[n+1];//已连续走了多少路
int[] visited=new int[n+1];//该点是否已被访问
Arrays.fill(dist, 10*10*10*10*10*10);
dist[1]=0;
//for(int i=1;i<=n;i++)
// System.out.println(dist[i]);
//System.out.println("duanduan");
Arrays.fill(visited, 0);
//for(int i=0;i<n+1;i++)
// System.out.println(visited[i]);
Arrays.fill(lianxi, 0);
//如果距离初始化的话就可以按照课本来
//否则按照下面步骤
for(int j=0;j<n;j++)
{
int v=-1;
for(int k=1;k<=n;k++)
{
if(visited[k]==0)
{
if(v==-1||(dist[k]<dist[v]))
v=k;
}
}
if(v==-1)//有没有都可以 前面for循环已经限定了次数
break;
visited[v]=1;//将点拿入
for(int mm=1;mm<=n;mm++)
{//大道
if(visited[mm]==0) {//这句话其实用不用都行 因为不这样也就是多搜索几遍而已
if(tag[v][mm]==0)
{
if(dist[mm]>dist[v]+edges[v][mm])
{
dist[mm]=dist[v]+edges[v][mm];
lianxi[mm]=0;
}
}//小道
else if(tag[v][mm]==1)
{
if(lianxi[v]==0)
{
long temp=dist[v]+edges[v][mm]*edges[v][mm];
if(temp<dist[mm])
{
dist[mm]=temp;
lianxi[mm]=edges[v][mm];
//System.out.println(temp);
}
}
else
{
long temp=dist[v]-lianxi[v]*lianxi[v]+(lianxi[v]+edges[v][mm])*(lianxi[v]+edges[v][mm]);
if(temp<dist[mm])
{
dist[mm]=temp;
lianxi[mm]=edges[v][mm]+lianxi[v];
}
}
}
}
}
}
System.out.println(dist[n]);
}
}