import java.io.*;
import java.util.*;
public class RouteDesign {
final static int maxnum = 100;
final static int minint = 0;
final static int maxint = 999999;
static int dist [] = new int [maxnum]; //当前路径中的最小带宽
static int mprev[] = new int [maxnum]; //当前节点的前一跳节点
static int c[][] = new int [maxnum][maxnum]; // 两个节点之间的带宽
static int hop[] = new int [maxnum]; //当前节点到源节点的跳数
public static void Dijkstra(int n,int v,int b,int dist[],int mprev[],int c[][]){
boolean s[] = new boolean[maxnum];
for(int i=1;i<=n;i++){
dist[i] = c[v][i]; //这个循环用来说明当前链路到源节点的带宽,寻找源节点可以到达的所有节点
s[i]=false;
if(dist[i]==minint)
mprev[i] = 0; //当前节点的前一跳节点为0
else{
mprev[i] = v; //否则前一跳为源节点
hop[i]=1; //重置跳数
}
}
dist[v] = maxint;
s[v] = true; //源节点s[v]为true
for(int i=2;i<=n;i++){
int tmp = b; //tmp为所要求的带宽
int u = v; //u为源节点
for(int j=1;j<=n;j++){
if(!s[j]&&dist[j]>=tmp){ //s[j]为0并且当前带宽大于要求带宽
u=j; //源节点等于当前节点
tmp=dist[j]; //保证带宽不会减小
}
}
s[u]=true;
for(int j=1;j<=n;j++){
int least = dist[u]; //least为u的带宽
if(c[u][j]<dist[u])
least=c[u][j]; //最得u到其他节点最小带宽值
if((!s[j])&&(least>dist[j])){ //如果当前节点到源点的路径中的带宽过小,更新当前节点最小带宽及路径
hop[j]=hop[u]+1;
mprev[j]=u;
dist[j]=least;
}
else if(!s[j]&&(least == dist[j])){ //如果相等则比较跳数,跳数小者成为当前节点的路径
if(hop[j]>hop[u]+1){
hop[j]=hop[u]+1;
mprev[j]= u;
dist[j]=least;
}
}
}
}
}
public static void searchPath(int mprev[],int v,int u,String output) throws FileNotFoundException{
OutputStream out = new FileOutputStream(output,true);
int que[] = new int[maxnum];
int tot=1;
que[tot]=u;
tot++;
int tmp = mprev[u]; //tmp为目的节点之前的节点
while(tmp!=v){ //目的节点与源节点v不相等
que[tot] =tmp;
tot++;
tmp=mprev[tmp]; //从目的节点回溯
}
que[tot]=v; //tot的值为回溯的次数
for(int i = tot;i>=i;i--){
if(i!=1){
int num=que[i];
try{
out.write(String.valueOf(num).getBytes()); //一个字符串转化为一个字节数组
out.write(",".getBytes());
}catch (IOException e){
e.printStackTrace(); //打印堆栈内容
}
}
else{
try{
out.write(String.valueOf(que[i]).getBytes());
out.write("\r\n".getBytes());
}catch(IOException e){
e.printStackTrace();
}
}
}
try{
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String input = args[0]; //而这个main方法有所不同的是:它是所有方法中最先运行的一个,所以没有其他方法给它传递参数,所以需要靠运行时命令行输入参数,所以String args,接收的是命令行的输入
String output = args[1];
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(new File(input))) );
String str = new String ();
int NodeNum=0;
int LineNum=0;
Vector<String>vstr = new Vector<String>();
Vector<String>dstr = new Vector<String>(); // java 中可以实现自动增长的对象数组
str = in.readLine(); //读取一个文本行
while(true){
str=in.readLine();
if(str.isEmpty()){
break;
}
vstr.add(str); // 把读入的对象加在vstr中
LineNum++;
}
in.readLine();
in.readLine();
while(true){
str=in.readLine();
if(str==null)
break;
else if(str.isEmpty())
break;
dstr.add(str); // 把目的读入的对象加在dstr中
}
String LastLine = (String)vstr.lastElement();
String[] strdata = LastLine.split("\\,");
int firststr = Integer.parseInt(strdata[0]);
int secondstr = Integer.parseInt(strdata[1]); //根据,分割录入信息
if(firststr<secondstr)
NodeNum = secondstr;
else
NodeNum = firststr;
for(int i=1;i<NodeNum;i++){
for(int j=1;j<NodeNum;j++){
c[i][j]=minint; //建立整个拓扑
}
}
for(int i=1;i<=LineNum;i++){
String Readvstr = (String)vstr.get(i-1); //get一个数字
String [] vstrdata = Readvstr.split("\\,");
int firstvstr = Integer.parseInt(vstrdata[0]);
int secondvstr = Integer.parseInt(vstrdata[1]);
int thirdvstr = Integer.parseInt(vstrdata[2]);
if(thirdvstr>c[firstvstr][secondvstr]){
c[firstvstr][secondvstr]=thirdvstr; //取最小带宽
c[secondvstr][firstvstr]=thirdvstr;
}
}
for(int i=1;i<NodeNum;i++){
dist[i]=minint;
hop[i]=minint;
}
int src,dst,bdw;
OutputStream out = new FileOutputStream(output,false);
out.write("".getBytes());
out.close();
for(int i=1;i<=dstr.size();i++){
String Readvstr = (String)dstr.get(i-1);
String sdstr[] =Readvstr.split(",");
src = Integer.parseInt(sdstr[0]);
dst = Integer.parseInt(sdstr[1]);
bdw = Integer.parseInt(sdstr[2]);
Dijkstra(NodeNum,src,bdw,dist,mprev,c);
searchPath(mprev,src,dst,output);
}
}
}