poj 2387
全裸的最短路,随便什么算法都能过
Poj 2253
这题可以用最小生成树来做,kruskal搞一下,如果1-2连同,此时的边就是青蛙跳的最大距离
while(scanf("%d",&n)&&n){ kase++; int xcount=0; for(int i=1;i<=n;i++) pre[i]=i; for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); for(int j=1;j<i;j++){ p[xcount].from=j; p[xcount].to=i; p[xcount++].cost=sqrt(double((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j]))); } } sort(p,p+xcount,cmp); for(int i=0;i<xcount;i++){ Union(p[i].from,p[i].to); if(Find(1)==Find(2)){ printf("Scenario #%d\nFrog Distance = %.3lf\n\n",kase,p[i].cost); break; } } }
poj 1797
这个题是求1-n的路中,最小边最大的一条路,可以用spfa变化下求。
dis[k]=max(dis[k],min(dis[x],edge[x][k]));
void spfa(int u){ queue<int> q; q.push(u); vis[u]=1; dis[u]=INF; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=0;i<v[x].size();i++){ int k=v[x][i]; if(dis[k]<min(dis[x],edge[x][k])){ dis[k]=min(dis[x],edge[x][k]); if(!vis[k]){ vis[k]=1; q.push(k); } } } } }
poj 3268
题意:给你m个有向边,n个牛先从自己家去x点,再回去,问哪个牛走的最长
题解:把给的有向边正着存一份,以x为源点求最短路,可以得到每个牛回家的距离。
再把所有有向边都倒过来存一遍,以x为源点求最短路,得到的是每个牛去的时候的距离。
想加找最大即可,两次spfa的事。
poj3259
题意:这题难点就在于读题。有m条无向的路,还有w条有向的路(虫洞),A one way path from S to E that also moves the traveler back T seconds.意思是这条有向边的权值是负的,然后要求的是FJ能否回到起点,意思就是说有没有负环,如果有负环的话,他会一直在那个负环里转,因为权值每次都变小了。
题解:用spfa(bellman-ford)求负环即可
vector<int> v[505]; int edge[505][505]; int dis[505]; int vis[505]; int xcount[505]; int n,m,w; void spfa(int u){ queue<int> q; q.push(u); vis[u]=1; dis[u]=0; xcount[u]++; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=0;i<v[x].size();i++){ int k=v[x][i]; if(dis[k]>dis[x]+edge[x][k]){ dis[k]=dis[x]+edge[x][k]; if(!vis[k]){ vis[k]=1; q.push(k); xcount[k]++; if(xcount[k]>n){ printf("YES\n"); return; } } } } } printf("NO\n"); }
POJ 1502
题意:这题又是英语来卡人,是说从1到各个点的最短路中的最大值,说到这里就是个水题了,然而看懂题目才是最难的。
poj 3660
题意:这题是给你m个有向边的关系,还有个确定有多少个牛的位置确定了
题解:Floyd暴力一遍,把所有有向边的关系都确定了,然后枚举每个牛,看他的入度出度之和是否为n-1
for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(edge[i][k]&&edge[k][j]) edge[i][j]=1; } } } int ans=0; for(int i=1;i<=n;i++){ int flag=0; for(int j=1;j<=n;j++){ if(i==j) continue; if(!(edge[i][j]||edge[j][i])) flag=1; } if(!flag) ans++; } printf("%d\n",ans);
poj 1511
这题就是个很显然的最短路,题目辣么长,然而难点在于数据量大!!!100w
题解:可以用dijkstra的堆优化和spfa来做。(刚学堆优化写的挫)
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 1000000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; struct edge{ int v,cost; edge(){} edge(int _v,int _cost):v(_v),cost(_cost){} }; struct edge2{ int u,v,w; edge2(){} edge2(int _u,int _v,int _w):u(_u),v(_v),w(_w){} }a[MAX]; struct node{ int id,val; node(){} node(int _id,int _v):id(_id),val(_v){} bool operator <(const node &a)const{ //重载<,使优先队列队首始终是val最小的元素 return val>a.val; } }x,y; vector<edge> v[MAX]; int vis[MAX]; int dis[MAX]; int n,m; LL dijkstra(int s){ priority_queue<node> q; memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); x.id=s; x.val=0; dis[s]=0; q.push(x); while(!q.empty()){ x=q.top(); q.pop(); int num=x.id; if(vis[num]) continue; vis[num]=1; for(int i=0;i<v[num].size();i++){ int to=v[num][i].v; int cost=v[num][i].cost; if(!vis[to]&&dis[to]>dis[num]+cost){ dis[to]=dis[num]+cost; y.id=to; y.val=dis[to]; q.push(y); } } } LL sum=0; for(int i=1;i<=n;i++) sum+=dis[i]; return sum; } int main(){ int t; scanf("%d",&t); while(t--){ LL ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) v[i].clear(); for(int i=1;i<=m;i++){ int u,vv,w; scanf("%d%d%d",&u,&vv,&w); a[i]=edge2(u,vv,w); v[u].push_back(edge(vv,w)); } ans+=dijkstra(1); for(int i=1;i<=n;i++) v[i].clear(); for(int i=1;i<=m;i++){ int u = a[i].u; int vv = a[i].v; int w = a[i].w; v[vv].push_back(edge(u,w)); } ans+=dijkstra(1); printf("%lld\n",ans); } return 0; }
下面是spfa的算法:时间复杂度和dijkstra的差不多(我以前用了LL 果断T了10次+)存结构体这种方法非常好,get
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 1000000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; struct edge{ int v,cost; edge(){} edge(int _v,int _c):v(_v),cost(_c){} }; struct edge2{ int u,v,w; edge2(){} edge2(int _u,int _v,int _w):u(_u),v(_v),w(_w){} }a[MAX]; vector<edge> v[MAX]; int dis[MAX]; int vis[MAX]; int n,m; LL spfa(int s){ queue<int> q; memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=0;i<v[x].size();i++){ int k=v[x][i].v; int cost=v[x][i].cost; if(dis[k]>dis[x]+cost){ dis[k]=dis[x]+cost; if(!vis[k]){ vis[k]=1; q.push(k); } } } } LL sum=0; for(int i=1;i<=n;i++) sum+=dis[i]; return sum; } int main(){ int t; scanf("%d",&t); while(t--){ LL ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) v[i].clear(); for(int i=1;i<=m;i++){ int u,vv,w; scanf("%d%d%d",&u,&vv,&w); a[i]=edge2(u,vv,w); v[u].push_back(edge(vv,w)); } ans+=spfa(1); for(int i=1;i<=n;i++) v[i].clear(); for(int i=1;i<=m;i++){ int u = a[i].u; int vv = a[i].v; int w = a[i].w; v[vv].push_back(edge(u,w)); } ans+=spfa(1); printf("%lld\n",ans); } return 0; }
poj 3159
题意:给你a,b,c三个数意思是a认为b不能比他多c个糖,p[b]-p[a]<=c,即为 p[b]<=p[a]+c,这就是显然的最短路,详见差分约束系统http://blog.csdn.net/xuezhongfenfei/article/details/8685313
题解:这题就是数据量大,用vector建图过不了,用dijkstra+heap+前向星可以过,spfa+stack也轻松掠过。答案就是求p[n]-p[1]的最大值,即dis[n](感觉我差分也没全搞懂,改天还得学学)(dijkstra和spfa复杂度接近)
spfa+stack
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 30000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; struct Edge{ int v,cost,next; }edge[150005]; struct node{ int id,val; bool operator<(const node &a)const{ return val>a.val; } }x; int head[30005]; int dis[30005]; int vis[30005]; int sstack[30005]; int tot; inline int read_int() { int ret=0; char tmp; while(!isdigit(tmp=getchar())); do{ ret=(ret<<3)+(ret<<1)+tmp-'0'; }while(isdigit(tmp=getchar())); return ret; } void add_edge(int a,int b,int c){ edge[tot].v=b; edge[tot].cost=c; edge[tot].next=head[a]; head[a]=tot++; } void spfa(int s){ memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); int top=0; sstack[top++]=s; dis[s]=0; vis[s]=1; while(top!=0){ int q=sstack[--top]; vis[q]=0; for(int i=head[q];i!=-1;i=edge[i].next){ int v=edge[i].v; int cost=edge[i].cost; if(dis[v]>dis[q]+cost){ dis[v]=dis[q]+cost; if(!vis[v]){ vis[v]=1; sstack[top++]=v; } } } } } int main(){ int n,m; scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); tot=0; for(int i=0;i<m;i++){ int a=read_int(); int b=read_int(); int c=read_int(); add_edge(a,b,c); } spfa(1); printf("%d\n",dis[n]); return 0; }
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 30000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; struct Edge{ int v,cost,next; }edge[150005]; struct node{ int id,val; bool operator<(const node &a)const{ return val>a.val; } }x; int head[30005]; int dis[30005]; int vis[30005]; int tot; inline int read_int() { int ret=0; char tmp; while(!isdigit(tmp=getchar())); do{ ret=(ret<<3)+(ret<<1)+tmp-'0'; }while(isdigit(tmp=getchar())); return ret; } void add_edge(int a,int b,int c){ edge[tot].v=b; edge[tot].cost=c; edge[tot].next=head[a]; head[a]=tot++; } void dijkstra(int s){ memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); priority_queue<node> q; x.id=s; x.val=0; dis[s]=0; q.push(x); while(!q.empty()){ x=q.top(); q.pop(); int num=x.id; if(vis[num]) continue; vis[num]=1; for(int i=head[num];i!=-1;i=edge[i].next){ int vv=edge[i].v; int cost=edge[i].cost; if(!vis[vv]&&dis[vv]>dis[num]+cost){ dis[vv]=dis[num]+cost; x.id=vv; x.val=dis[vv]; q.push(x); } } } } int main(){ int n,m; scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); tot=0; for(int i=0;i<m;i++){ int a=read_int(); int b=read_int(); int c=read_int(); add_edge(a,b,c); } dijkstra(1); printf("%d\n",dis[n]); return 0; }
poj 1062
题意:一个比较明显的最短路,加上了等级。
题解:枚举最高等级,然后把等级不满足的点直接vis[x]=1记作已经访问过。
然后dijkstra即可
for(int i=mini;i<=maxn;i++){ memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); for(int j=1;j<=n;j++){ if(level[j]>i||i-level[j]>m) vis[j]=1; } dis[0]=0; while(1){ int x=n+1; for(int i=0;i<=n;i++){ if(!vis[i]&&dis[i]<dis[x]) x=i; } if(x==n+1) break; vis[x]=1; for(int i=0;i<=n;i++){ if(!vis[i]) dis[i]=min(dis[i],dis[x]+edge[x][i]); } } ans=min(ans,dis[1]); } printf("%d\n",ans);
lightoj 1074
题意:很明显是最短路哇
题解:spfa判下负环即可。水水哒
/**********************************************************************************************************************************************************************************/
HDU 4370(转自kuangbin大神blog)(绝对好题***)
显然,题目给的是一个0/1规划模型。
解题的关键在于如何看出这个模型的本质。
3个条件明显在刻画未知数之间的关系,从图论的角度思考问题,容易得到下面3个结论:
1.X12+X13+...X1n=1 于是1号节点的出度为1
2..X1n+X2n+...Xn-1n=1 于是n号节点的入度为1
3.∑Xki =∑Xij 于是2~n-1号节点的入度必须等于出度
于是3个条件等价于一条从1号节点到n号节点的路径,故Xij=1表示需要经过边(i,j),代价为Cij。Xij=0表示不经过边(i,j)。注意到Cij非负且题目要求总代价最小,因此最优答案的路径一定可以对应一条简单路径。
最终,我们直接读入边权的邻接矩阵,跑一次1到n的最短路即可,记最短路为path。
以上情况设为A
非常非常非常非常非常非常非常非常抱歉,简单路径只是充分条件,但不必要。(对造成困扰的队伍深表歉意)
漏了如下的情况B:
从1出发,走一个环(至少经过1个点,即不能是自环),回到1;从n出发,走一个环(同理),回到n。
容易验证,这是符合题目条件的。且A || B为该题要求的充要条件。
由于边权非负,于是两个环对应着两个简单环。
本程序用SPFA来完成最短路。
但是由于要计算从出发点出发的闭环的路径长度。
所以要在普通SPFA的基础上做点变化。
就是把dist[start]设为INF。同时一开始并不是让出发点入队,而是让
出发点能够到达的点入队。
<span style="font-size:12px;">#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 30000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; inline int read_int() { int ret=0; char tmp; while(!isdigit(tmp=getchar())); do{ ret=(ret<<3)+(ret<<1)+tmp-'0'; }while(isdigit(tmp=getchar())); return ret; } struct Edge{ int v,cost,next; }edge[100000]; int head[305]; int dis[305]; int vis[305]; int tot; void add_edge(int a,int b,int c){ edge[tot].v=b; edge[tot].cost=c; edge[tot].next=head[a]; head[a]=tot++; } void spfa(int s){ memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); queue<int> q; for(int i=head[s];i!=-1;i=edge[i].next){ int k=edge[i].v; if(k!=s){ dis[k]=edge[i].cost; vis[k]=1; q.push(k); } } while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i!=-1;i=edge[i].next){ int k=edge[i].v; int cost=edge[i].cost; if(dis[k]>dis[x]+cost){ dis[k]=dis[x]+cost; if(!vis[k]){ vis[k]=1; q.push(k); } } } } } int main(){ int n; while(~scanf("%d",&n)){ memset(edge,INF,sizeof(edge)); memset(head,-1,sizeof(head)); tot=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ int a; scanf("%d",&a); add_edge(i,j,a); } } spfa(1); int path=dis[n]; int c1=dis[1]; spfa(n); int c2=dis[n]; printf("%d\n",min(path,c1+c2)); } return 0; }
poj 3169
题意:当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些。FJ有N(2<=N<=1000)头奶牛,编号从1到N,沿一条直线站着等候喂食。奶牛排在队伍中的顺序和它们的编号是相同的。因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上。即使说,如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标。
一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数L。另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数D。给出ML条关于两头奶牛间有好感的描述,再给出MD条关于两头奶牛间存有反感的描述。(1<=ML,MD<=10000,1<=L,D<=1000000)
你的工作是:如果不存在满足要求的方案,输出-1;如果1号奶牛和N号
奶牛间的距离可以任意大,输出-2;否则,计算出在满足所有要求的情况下,1号奶牛和N号奶牛间可能的最大距离。
题解:这题给出了一些好感的关系,首先题目说每个牛站的位置是按照标号顺序的,所以3号的位置肯定大于等于1号。
所以一种情况就是AB最大相差C,就是B-A<=C,即为B<=A+C,这是A->B之间有一条权值C的有向边。
AB相差最小为C,就是B-A>=C,即为B>=A+C,化成A<=B-C,这是B->A之间有一条权值为-C的有向边
建图之后spfa跑一遍(因为有负权值),如果dis[n]==INF的时候就是1-n之间的没有最短路,可以任意距离,输出-2
有负环就是-1这个队伍不能排(我一开始-1 -2搞反了)
<span style="font-size:12px;">#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 30000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; inline int read_int() { int ret=0; char tmp; while(!isdigit(tmp=getchar())); do{ ret=(ret<<3)+(ret<<1)+tmp-'0'; }while(isdigit(tmp=getchar())); return ret; } struct Edge{ int v,cost,next; }edge[20000]; int head[1005]; int dis[1005]; int vis[1005]; int xcount[1005]; int tot; int flag; void add_edge(int a,int b,int c){ edge[tot].v=b; edge[tot].cost=c; edge[tot].next=head[a]; head[a]=tot++; } void spfa(int s,int n){ memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); memset(xcount,0,sizeof(xcount)); queue<int> q; dis[s]=0; vis[s]=1; xcount[s]++; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i!=-1;i=edge[i].next){ int k=edge[i].v; int cost=edge[i].cost; //printf("%d %d %d \n",x,k,cost); if(dis[k]>dis[x]+cost){ dis[k]=dis[x]+cost; if(!vis[k]){ vis[k]=1; xcount[k]++; q.push(k); if(xcount[k]>n){ flag=1; return ; } } } } } } int main(){ int n,l,d; scanf("%d%d%d",&n,&l,&d); tot=0; memset(head,-1,sizeof(head)); for(int i=0;i<l;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); } for(int i=0;i<d;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(b,a,-c); } flag=0; spfa(1,n); if(flag) printf("-1\n"); else if(dis[n]==INF) printf("-2\n"); else printf("%d\n",dis[n]); return 0; } </span>
hdu 4725
题意:给你n个点,每个点属于某个层,点之间有m条无向边,相邻的层之间还能互相走,花费是c
题解:首先看百度上说要拆点,后来学长没用拆点就过去了。
记录每个层有哪些点,然后用dijkstra+heap的时候,点的结构体中要加个判断is_node,如果是点,他就可以走向他所连的边,还有他的上一层或者下一层,都进队。
如果是层,那么可以把这层上的所有点(未访问过并且dis被更新过的)放进队列中,即可。(前向星建图head没有初始化又看了好久,还得多练,这题也是虚掉了不敢做,so weak)
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std; #define MAX 30000+5 #define MAXN 100000+5 typedef long long LL; typedef unsigned long long ull; const double pi=3.141592653589793; const int INF=0x3f3f3f3f; const int INFF=1e9; const double inf=1e18; const double eps=1e-10; const int mod=1000000007; const int prime=999983; inline int read_int(){ int ret=0; char tmp; while(!isdigit(tmp=getchar())); do{ ret=(ret<<3)+(ret<<1)+tmp-'0'; }while(isdigit(tmp=getchar())); return ret; } struct Node{ int v,val; bool is_node; bool operator < (const Node &a)const{ return val > a.val; } }; struct Edge{ int v,cost,next; }edge[2*MAXN]; int n,m,c; vector<int> v[MAXN]; int lay[MAXN]; int head[MAXN]; int dis[MAXN]; int vis[MAXN]; int vis_l[MAXN]; int tot; int max_l,min_l; void add_edge(int a,int b,int c){ edge[tot]=(Edge){b,c,head[a]}; head[a]=tot++; } void dijkstra(int s){ memset(vis,0,sizeof(vis)); memset(vis_l,0,sizeof(vis_l)); memset(dis,INF,sizeof(dis)); priority_queue<Node> q; q.push((Node){s,0,1}); dis[s]=0; while(!q.empty()){ Node now=q.top(); q.pop(); int num=now.v; if(now.is_node){ if(vis[num]) continue; vis[num]=1; for(int i=head[num];i!=-1;i=edge[i].next){ int k=edge[i].v; int cost=edge[i].cost; if(!vis[k]&&dis[k]>dis[num]+cost){ dis[k]=dis[num]+cost; q.push((Node){k,dis[k],1}); } } if(lay[num]>min_l){ q.push((Node){lay[num]-1,dis[num]+c,0}); } if(lay[num]<max_l){ q.push((Node){lay[num]+1,dis[num]+c,0}); } } else{ if(vis_l[num]) continue; vis_l[num]=1; for(int i=0;i<v[num].size();i++){ int k=v[num][i]; if(!vis[k]&&dis[k]>now.val){ dis[k]=now.val; q.push((Node){k,dis[k],1}); } } } } } int main(){ int T; scanf("%d",&T); for(int t=1;t<=T;t++){ scanf("%d%d%d",&n,&m,&c); tot=0; max_l=0; min_l=INF; memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++) v[i].clear(); for(int i=1;i<=n;i++){ scanf("%d",&lay[i]); v[lay[i]].push_back(i); max_l=max(max_l,lay[i]); min_l=min(min_l,lay[i]); } for(int i=0;i<m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } dijkstra(1); printf("Case #%d: ",t); if(dis[n]==INF) printf("-1\n"); else printf("%d\n",dis[n]); } return 0; }
还有个神马最短路+最大流还不会,改天做完了再发