知识点扫盲加基本板子总结
知识点扫盲加基本板子总结
数据结构
并查集
#include<bits/stdc++.h>
#define N 105
using namespace std;
int fa[N];
int n;
int find(int x)
{
if (x==fa[x]) return x; else return (fa[x]=find(fa[x]));
}
void merge(int x,int y)
{
int fx=find(x),fy=find(y);
if (fx!=fy) fa[fx]=fy;
}
void init()
{ scanf("%d",&n);
for (int i=1; i<=n; i++) fa[i]=i;
}
int main()
{
return 0;
}
图论
Floyd
题目链接['http://codeforces.com/contest/296/problem/D']
#include<bits/stdc++.h>
#define N 505
#define ll long long
#define inf 100000000000000LL
using namespace std;
int n;
int b[N];
ll f[N][N],ans[N];
bool vis[N];
void init()
{
scanf("%d",&n);
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++) scanf("%lld",&f[i][j]);
}
for (int i=1; i<=n; i++) scanf("%d",&b[i]);
}
void floyd()
{
for (int i=n; i>=1; i--)
{
vis[b[i]]=1;
for (int j=1; j<=n; j++)
for (int k=1; k<=n; k++)
{
f[j][k]=min(f[j][k],f[j][b[i]]+f[b[i]][k]);
}
ll sum=0;
for (int j=1; j<=n; j++)
for (int k=1; k<=n; k++)
{
if (!vis[j] || !vis[k]) continue;
sum+=f[j][k];
}
ans[i]=sum;
}
}
void print()
{
for (int i=1; i<=n; i++) printf("%lld ",ans[i]);
}
int main()
{
init();
floyd();
print();
return 0;
}
堆优化Dijkstra
题目链接['http://codeforces.com/contest/20/problem/C']
#include<bits/stdc++.h>
#define N 100005
#define M 100005
#define inf 100000000000000000LL
#define ll long long
using namespace std;
int n,m,st,ed;
ll dis[N];
ll path[N];
bool vis[N];
vector<pair<ll,ll> >E[M+10];
priority_queue<pair<ll,ll> > Q;
void insedge(int u,int v,ll val)
{
E[u].push_back(make_pair(v,val));
}
void init()
{
scanf("%d%d",&n,&m);
for (int i=1; i<=m; i++)
{
int u,v;
ll val;
scanf("%d%d%lld",&u,&v,&val);
insedge(u,v,val);
insedge(v,u,val);
}
st=1; ed=n;
for (int i=1; i<=n; i++) dis[i]=inf;
dis[st]=0;
}
void dijkstra()
{
Q.push(make_pair(dis[st],st));
while (!Q.empty())
{
int v=Q.top().second;
ll val=-Q.top().first;
Q.pop();
if (val!=dis[v]) continue;
if (vis[v]) continue;
vis[v]=1;
for (int i=0; i<E[v].size(); i++)
{
int u=E[v][i].first;
ll cost=E[v][i].second;
if (dis[u]>dis[v]+cost)
{
dis[u]=dis[v]+cost;
path[u]=v;
Q.push(make_pair(-dis[u],u));
}
}
}
}
void dfs(int x)
{
if (x!=st) dfs(path[x]);
printf("%d ",x);
}
void print()
{
if (dis[ed]==inf) printf("-1\n");
else
{
int x=ed;
dfs(x);
}
}
int main()
{
init();
dijkstra();
print();
return 0;
}
SPFA
题目链接['http://codeforces.com/contest/20/problem/C']
#include<bits/stdc++.h>
#define mp(a,b) make_pair(a,b)
#define ll long long
#define inf 100000000000000000LL
#define N 200005
using namespace std;
vector<pair<int,ll> > E[N];
int path[N];
ll dis[N];
queue<int>q;
bool vis[N];
int n,m;
void insedge(int u,int v,ll val)
{
E[u].push_back(mp(v,val));
}
void spfa()
{
q.push(1);
while (!q.empty())
{
int u=q.front(); q.pop();
vis[u]=0;
for (int i=0; i<E[u].size(); i++)
{
int v=E[u][i].first;
ll cost=E[u][i].second;
if (dis[v]>dis[u]+cost)
{
dis[v]=dis[u]+cost; path[v]=u;
if (dis[v]>dis[n]) continue;
if (!vis[v])
{
q.push(v); vis[v]=1;
}
}
}
}
}
void init()
{
scanf("%d%d",&n,&m);
for (int i=1; i<=m; i++)
{
int u,v; ll val;
scanf("%d%d%lld",&u,&v,&val);
insedge(u,v,val); insedge(v,u,val);
}
for (int i=1; i<=n; i++) dis[i]=inf;
dis[1]=0;
}
void dfs(int x)
{
if (x!=1) dfs(path[x]);
printf("%d ",x);
}
void print()
{
if (dis[n]==inf) printf("-1\n");
else
{
int x=n;
dfs(x);
}
}
int main()
{
init();
spfa();
print();
return 0;
}
最小生成树Kruskal
题目链接['http://acm.hdu.edu.cn/showproblem.php?pid=1863']
#include<bits/stdc++.h>
#define N 100005
#define ll long long
using namespace std;
int n,m;
int fa[N];
struct Edge
{
int u,v; long long val;
operator < ( Edge a){
return this->val<a.val;
}
}a[N];
int find(int x)
{
if (x==fa[x]) return x; else return (fa[x]=find(fa[x]));
}
int merge(int x,int y)
{
int fx=find(x),fy=find(y);
if (fx!=fy)
{
fa[fx]=fy; return 1;
}
return 0;
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n==0 ) break;
for (int i=1; i<=n; i++)
scanf("%d%d%lld",&a[i].u,&a[i].v,&a[i].val);
sort(a+1,a+n+1);
//for (int i=1; i<=n; i++)
// cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].val<<endl;
int sum=0; ll ans=0;
for (int i=0; i<=m; i++) fa[i]=i;
for (int i=1; i<=n; i++)
{
int flag=merge(a[i].u,a[i].v);
if (flag==1) sum++,ans+=a[i].val;
// if (sum==m-1) break;
}
if (sum!=(m-1)) printf("?\n");
else printf("%lld\n",ans);
}
return 0;
}
最小生成树prim算法
题目链接[]
我太蒟蒻了,所以神犇们留下意见让我跪膜