floyd
dijstra
spfa
bzoj1001
浅析最大最小定理在信息学竞赛中的应用
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define MAXN 2000001
#define INF (~0U>>1)
#define F(i,j,n) for(int i=j;i<=n;i++)
#include<queue>
#include<vector>
using namespace std;
vector<int>edge[MAXN],weight[MAXN];
bool vst[MAXN];
int n,m,x,t,dis[MAXN];
struct Heapnode
{
int dist,num;
bool operator <(const Heapnode & x)const{
return dist>x.dist;
}
};
void solve()
{
int x=max(n,m);
int p,minn=INF;
F(i,1,x-1)
{
scanf("%d",&p);
minn=min(p,minn);
}
if(minn==INF) minn=0;
printf("%d\n",minn);
return ;
}
priority_queue<Heapnode> Q;
int main()
{
scanf("%d%d",&n,&m);
if(n==1||m==1)
{
solve();
return 0;
}
t=(n-1)*(m-1)*2+1;
F(i,1,n)
F(j,1,m-1)
{
scanf("%d",&x);
if(i==1)
{
edge[t].push_back(2*j);
weight[t].push_back(x);
edge[2*j].push_back(t);
weight[2*j].push_back(x);
}
if(i==n)
{
int p=2*(n-2)*(m-1)+2*j-1;
edge[0].push_back(p);
weight[0].push_back(x);
edge[p].push_back(0);
weight[p].push_back(x);
}
if(i<n&&i>1)
{
int p=2*(m-1)*(i-1)+2*j;
int q=2*(m-1)*(i-2)+2*j-1;
edge[p].push_back(q);
weight[p].push_back(x);
edge[q].push_back(p);
weight[q].push_back(x);
}
}
F(i,1,n-1)
F(j,1,m)
{
scanf("%d",&x);
if(j==1)
{
int p=2*(m-1)*(i-1)+1;
edge[0].push_back(p);
weight[0].push_back(x);
edge[p].push_back(0);
weight[p].push_back(x);
}
if(j==m)
{
int p=2*(m-1)*i;
edge[t].push_back(p);
weight[t].push_back(x);
edge[p].push_back(t);
weight[p].push_back(x);
}
if(j>1&&j<m)
{
int p=2*(m-1)*(i-1)+2*(j-1);
edge[p].push_back(p+1);
weight[p].push_back(x);
edge[p+1].push_back(p);
weight[p+1].push_back(x);
}
}
F(i,1,n-1)
F(j,1,m-1)
{
scanf("%d",&x);
int p=2*(m-1)*(i-1)+2*j-1;
edge[p].push_back(p+1);
weight[p].push_back(x);
edge[p+1].push_back(p);
weight[p+1].push_back(x);
}
F(i,1,t) dis[i]=INF;
dis[0]=0;
memset(vst,false,sizeof(vst));
Q.push((Heapnode){0,0});
while(!Q.empty())
{
Heapnode x=Q.top();
Q.pop();
if(vst[x.num]) continue;
vst[x.num]=true;
for(int i=0;i<edge[x.num].size();i++)
{
if(dis[edge[x.num][i]]>dis[x.num]+weight[x.num][i])
{
dis[edge[x.num][i]]=dis[x.num]+weight[x.num][i];
Q.push((Heapnode){dis[edge[x.num][i]],edge[x.num][i]});
}
}
}
printf("%d\n",dis[t]);
return 0;
}
bzoj1726
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define inf (~0U>>1)
using namespace std;
inline int read()
{
int num=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
num=num*10+ch-'0';
ch=getchar();
}
return num;
}
int m,n,d,head[5005],cnt;
int dis[5005][2];
int tmp,ans=inf;
int a,b,x;
bool v[5005];
struct edge{
int f,t,l;
}e[200005];
queue<int> Q;
void add(int f,int t,int l)
{
e[++cnt].f=head[f];
e[cnt].t=t;
e[cnt].l=l;
head[f]=cnt;
}
void spfa(int start,int num)
{
memset(v,0,sizeof(v));
dis[start][num]=0;
Q.push(start);
v[start]=1;
while(!Q.empty()){
int y=Q.front();
Q.pop();
v[y]=0;
for(int i=head[y];i;i=e[i].f){
if(dis[e[i].t][num]>dis[y][num]+e[i].l)
{
dis[e[i].t][num]=dis[y][num]+e[i].l;
if(!v[e[i].t])
{
Q.push(e[i].t);
v[e[i].t]=1;
}
}
}
}
}
int main()
{
memset(dis,0x7f,sizeof(dis));
n=read();
m=read();
for(int i=1;i<=m;i++){
a=read();
b=read();
x=read();
add(a,b,x);
add(b,a,x);
}
spfa(1,0);
spfa(n,1);
F(i,1,n) for(int j=head[i];j;j=e[j].f){
tmp=dis[i][0]+dis[e[j].t][1]+e[j].l;
if(tmp>dis[n][0]&&tmp<ans) ans=tmp;
}
printf("%d\n",ans);
}
两次spfa分别从头和尾
之后枚举每一条边大于最小值的最小值
bzoj2763
分层图
bzoj1614
二分答案
silver
Claris说普及组
不离散化?
bzoj1774
最小生成树
bzoj3943
求最大生成树
bzoj1050
从小到大加边
bzoj3714
连边
最小生成树
bzoj4554
二分图
什么都不会QwQ
bzoj 1529
裸题,卡内存
bzoj1051奇怪
bzoj1093
dag找点权值最大
拓扑排序