/*
hdu 1599 ( find the mincost route )
Floyed求最小环
每个环一定是 由 i j k 构成
假设k是环中的max 要成环 就要保证不是链(md废话)
利用Floyed的最外层循环含义 i-j最短路经过的点编号<k
那个我们在 限制i<j<k 那么f[i][j]+g[i][k]+g[k][j]
一定能构成一个环 并且点数>=3 因为i j k 互不相同
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 110
#define inf 2000000
using namespace std;
int n,m,f[maxn][maxn],g[maxn][maxn],ans;
void Clear(){
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
f[i][j]=g[i][j]=inf;
ans=inf;
}
int min(int x,int y){
return x<y?x:y;
}
void Floyed(){
for(int k=1;k<=n;k++){
for(int i=1;i<k;i++)
for(int j=i+1;j<k;j++)
ans=min(ans,f[i][j]+g[i][k]+g[k][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
int main()
{
while(~scanf("%d%d",&n,&m)){
Clear();int u,v,t;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&t);
f[u][v]=min(f[u][v],t);
f[v][u]=min(f[v][u],t);
g[u][v]=g[v][u]=f[u][v];
}
Floyed();
if(ans==inf)printf("It's impossible.\n");
else printf("%d\n",ans);
}
return 0;
}
/*
hdu 2807 ( The Shortest Path )
n*n判断矩阵相乘是不是等于另一矩阵
比较快的矩阵比较方法 get了
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 81
#define inf 0x3f3f3f3f
using namespace std;
int n,m,Q,A[maxn][maxn],f[maxn][maxn],B[maxn];
struct node{
int c[maxn][maxn];
}p[maxn];
void Clear(){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
A[i][j]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=inf;
}
void Insert(int x,int y){
for(int i=1;i<=m;i++)B[i]=0;
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
B[i]+=p[x].c[i][j]*A[y][j];
int falg=0;
for(int k=1;k<=n;k++){
if(k==x||k==y)continue;
falg=0;
for(int i=1;i<=m;i++)
if(A[k][i]!=B[i]){
falg=1;break;
}
if(!falg)f[x][k]=1;
}
}
void Floyed(){
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
int main()
{
while(1){
scanf("%d%d",&n,&m);
if(n==0&&m==0)break;
Clear();int u,v;
for(int k=1;k<=n;k++)
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++){
scanf("%d",&p[k].c[i][j]);
A[k][i]+=p[k].c[i][j]*j;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
Insert(i,j);
Floyed();
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&u,&v);
if(f[u][v]==inf)printf("Sorry\n");
else printf("%d\n",f[u][v]);
}
}
return 0;
}
/*
hdu 2224 ( The shortest path )
不知道为啥出现在最短路分类里 我纯dp做的
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 210
#define inf 0x3f3f3f3f
using namespace std;
int n;
double x[maxn],y[maxn],g[maxn][maxn],f[maxn][maxn],ans;
struct point{
double x,y;
}p[maxn];
int cmp(const point &a,const point &b){
return a.x<b.x;
}
void Clear(){
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
f[i][j]=inf;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
g[i][j]=inf;
ans=inf;
}
double Get(int i,int j){
return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
}
int max(int a,int b){
return a>b?a:b;
}
int main()
{
while(scanf("%d",&n)!=EOF){
Clear();
for(int i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+1+n,cmp);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
g[i][j]=g[j][i]=Get(i,j);
f[1][1]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
int k=max(i,j)+1;
f[i][k]=min(f[i][k],f[i][j]+g[j][k]);
f[k][j]=min(f[k][j],f[i][j]+g[i][k]);
}
for(int i=1;i<=n;i++){
ans=min(ans,f[i][n]+g[i][n]);
ans=min(ans,f[n][i]+g[n][i]);
}
printf("%.2f\n",ans);
}
return 0;
}
/*
hdu 1598 ( find the most comfortable road )
再次被分类坑了...
是并茶几不是最短路..
枚举每组数据所用的最小的边-最大的边
有点慢 不过还好并茶几飞快
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1010
using namespace std;
int n,m,Q,fa[maxn],mx;
struct node{
int u,v,t;
bool operator < (const node &a) const {
return t<a.t;
}
}e[maxn];
int init(){
int x=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
}
int find(int x){
if(x!=fa[x])fa[x]=find(fa[x]);
return fa[x];
}
int min(int x,int y){
return x<y?x:y;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
int u,v,t;
for(int i=1;i<=m;i++){
u=init();v=init();t=init();
e[i].u=u;e[i].v=v;e[i].t=t;
}
sort(e+1,e+1+m);
Q=init();
while(Q--){
u=init();v=init();mx=0x7fffffff;
for(int k=1;k<=m;k++){
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=k;i<=m;i++){
int r1=find(e[i].u);
int r2=find(e[i].v);
if(r1!=r2)fa[r2]=r1;
if(find(u)==find(v)){
mx=min(mx,e[i].t-e[k].t);break;
}
}
}
if(mx==0x7fffffff)printf("-1\n");
else printf("%d\n",mx);
}
}
return 0;
}
/*+几条边不存在桥*/
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#define maxn 1010
using namespace std;
int n,m,num,head[maxn],low[maxn],dfn[maxn],topt,f[maxn],r[maxn],sum,belong[maxn];
stack<int>s;
struct node{
int v,pre;
}e[maxn*2];
int init(){
int x=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
}
void Clear(){
num=0;topt=0;sum=0;
for(int i=0;i<=n;i++)f[i]=0;
for(int i=0;i<=n;i++)r[i]=0;
for(int i=0;i<=n;i++)low[i]=0;
for(int i=0;i<=n;i++)dfn[i]=0;
for(int i=0;i<=n;i++)head[i]=-1;
for(int i=0;i<=n;i++)belong[i]=0;
while(!s.empty())s.pop();
}
void Add(int from,int to){
e[num].v=to;
e[num].pre=head[from];
head[from]=num++;
}
void Dfs(int x,int from){
low[x]=dfn[x]=++topt;
f[x]=1;s.push(x);
for(int i=head[x];i!=-1;i=e[i].pre){
int v=e[i].v;
if(i==(from^1))continue;
if(dfn[v]==0){
Dfs(v,i);low[x]=min(low[x],low[v]);
}
else if(f[v])low[x]=min(low[x],dfn[v]);
}
if(low[x]==dfn[x]){
sum++;
while(s.top()!=x){
belong[s.top()]=sum;f[s.top()]=0;s.pop();
}
belong[s.top()]=sum;f[s.top()]=0;s.pop();
}
}
int main()
{
while(~scanf("%d%d",&n,&m)){
Clear();int u,v;
for(int i=1;i<=m;i++){
u=init();v=init();
Add(u,v);Add(v,u);
}
for(int i=1;i<=n;i++)
if(dfn[i]==0)Dfs(i,-1);
for(int u=1;u<=n;u++)
for(int i=head[u];i!=-1;i=e[i].pre){
int v=e[i].v;
if(belong[u]!=belong[v])r[belong[u]]++;
}
int cnt=0;
for(int i=1;i<=sum;i++)
if(r[i]==1)cnt++;
printf("%d\n",(cnt+1)/2);
}
return 0;
}
/*hdu 3768 ( Shopping ) SPFA+全排列*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 200010
using namespace std;
int T,n,m,k,c[20],num,head[maxn],dis[maxn],g[20][20],f[maxn],a[20];
long long ans;
struct node{
int v,t,pre;
}e[maxn*10];
queue<int>q;
int init(){
int x=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
}
void Clear(){
num=0;ans=0x7fffffff;
memset(head,0,sizeof(head));
memset(g,127/3,sizeof(g));
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
}
void Add(int from,int to,int dis){
num++;e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
void SPFA(int s){
memset(dis,127/3,sizeof(dis));
memset(f,0,sizeof(f));
dis[s]=0;f[s]=1;q.push(s);
while(!q.empty()){
int u=q.front();
f[u]=0;q.pop();
for(int i=head[u];i;i=e[i].pre){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].t){
dis[v]=dis[u]+e[i].t;
if(f[v]==0){
f[v]=1;q.push(v);
}
}
}
}
}
int main()
{
T=init();
while(T--){
n=init();m=init();
Clear();int u,v,t;
for(int i=1;i<=m;i++){
u=init();v=init();t=init();
Add(u,v,t);Add(v,u,t);
}
k=init();
for(int i=1;i<=k;i++){
c[i]=init();a[i]=i;
}
SPFA(0);
for(int i=1;i<=k;i++)
g[0][i]=g[i][0]=dis[c[i]];
for(int i=1;i<=k;i++){
SPFA(c[i]);
for(int j=1;j<=k;j++)
g[i][j]=dis[c[j]];
}
do{
long long mx=0;
for(int i=1;i<=k+1;i++)
mx+=g[a[i-1]][a[i]];
ans=min(ans,mx);
}while(next_permutation(a+1,a+k+1));
cout<<ans<<endl;
}
return 0;
}
/*poj 1679 次小生成树n*n算法 get了*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 110
using namespace std;
int T,n,m,num,head[maxn],fa[maxn],c[maxn*maxn],mx[maxn][maxn],mst,ans;
struct node{
int u,v,t,o;
bool operator < (const node &x) const{
return t<x.t;
}
}p[maxn*maxn];
struct edge{
int v,t,pre,x;
}e[maxn*maxn*2];
void Clear(){
num=mst=0;ans=0x7fffffff;
for(int i=0;i<=n;i++)fa[i]=i;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
mx[i][j]=0;
for(int i=0;i<=m;i++)c[i]=0;
for(int i=0;i<=n;i++)head[i]=0;
}
void Add(int from,int to,int dis,int numb){
num++;e[num].v=to;
e[num].t=dis;
e[num].x=numb;
e[num].pre=head[from];
head[from]=num;
}
int find(int x){
if(x!=fa[x])fa[x]=find(fa[x]);
return fa[x];
}
void MST(){
int tot=0;
for(int i=1;i<=m;i++){
int r1=find(p[i].u);
int r2=find(p[i].v);
if(r1!=r2){
tot++;mst+=p[i].t;
c[p[i].o]=1;fa[r2]=r1;
}
if(tot==n-1)break;
}
}
void Dfs(int s,int now,int from,int mxx){
mx[s][now]=mxx;
for(int i=head[now];i;i=e[i].pre){
int v=e[i].v;
if(v==from)continue;
if(c[e[i].x]==0)continue;
Dfs(s,v,now,max(mxx,e[i].t));
}
}
void Mx(){
for(int i=1;i<=n;i++)
Dfs(i,i,-1,0);
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
Clear();int u,v,t;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&t);
Add(u,v,t,i);Add(v,u,t,i);
p[i].u=u;p[i].v=v;
p[i].t=t;p[i].o=i;
}
sort(p+1,p+1+m);
MST();Mx();
for(int i=1;i<=m;i++){
if(c[p[i].o])continue;
int len=mx[p[i].u][p[i].v];
ans=min(ans,mst+p[i].t-len);
}
if(ans==mst)printf("Not Unique!\n");
else printf("%d\n",mst);
}
return 0;
}