八数码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mst(s,_s) memset(s, _s, sizeof(s))
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int N = 1e6+100;
int T,n,m;
int bfs(string state)
{
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
unordered_map<string,int>d;
d[state]=0;
queue<string>q;
q.push(state);
while(q.size())
{
auto t=q.front();
q.pop();
if(t=="12345678x") return d[t];
int pos=t.find('x');
int x=pos/3,y=pos%3;
for(int i=0;i<4;i++)
{
string ns=t;
int nx=x+dx[i],ny=y+dy[i];
if(nx<0 || nx>=3 || ny<0 || ny>=3) continue;
int n_pos=nx*3+ny;
swap(ns[pos],ns[n_pos]);
if(d.count(ns)) continue;
d[ns]=d[t]+1;
q.push(ns);
}
}
return -1;
}
int main() {
string s;
for(int i=0;i<9;i++)
{
char t;
cin>>t;
s=s+t;
}
cout<<bfs(s)<<endl;
return 0;
}
树的重心
思路
dfs枚举:
- 枚举哪个点被删去
- dfs可以统计子树大小
- 然后各种去max
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, M = N * 2;
int n;
int h[N], e[M], ne[M], idx;
int ans = N;
bool st[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
int _u;
int dfs(int u)
{
st[u]=1;
int sum=0;
int maxv=0;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(st[j]) continue;
int k=dfs(j);
sum+=k;
maxv = max(maxv,k);
}
sum++;
maxv = max(maxv,n-sum);
if(maxv < ans)
{
ans=maxv;
_u=u;
}
return sum;
}
int main()
{
scanf("%d", &n);
memset(h, -1, sizeof h);
for (int i = 0; i < n - 1; i ++ )
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b), add(b, a);
}
dfs(1);
printf("%d\n", ans);
return 0;
}
有向图的拓扑序列
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
queue<int>q;
int in[N];
int n,m;
int e[N],h[N],ne[N],idx;
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void tp_sort(){
vector<int>res;
for(int i=1;i<=n;i++)
if(in[i]==0)
q.push(i);
while(q.size()){
int t=q.front();
q.pop();
res.push_back(t);
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
in[j]--;
if(in[j]==0) q.push(j);
}
}
if(res.size()==n)
for(int i=0;i<res.size();i++)
cout<<res[i]<<' ';
else cout<<"-1";
cout<<endl;
}
int main(){
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--){
int a,b;
cin>>a>>b;
add(a,b);
in[b]++;
}
tp_sort();
return 0;
}
最短路(稠密图):最短路系列,在中间st,bfs前面st
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 510;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n-1;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
if(!st[j] && (t==-1 || dist[t]>dist[j]))
t=j;
st[t]=1;
for(int j=1;j<=n;j++)
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
if(dist[n]>=0x3f3f3f3f/2) return -1;
return dist[n];
}
int main()
{
scanf("%d%d", &n, &m);
memset(g, 0x3f, sizeof g);
while (m -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
g[a][b] = min(g[a][b], c);
}
printf("%d\n", dijkstra());
return 0;
}
稀疏图
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include<vector>
using namespace std;
typedef pair<int, int> pll;
const int N = 1e6 + 10;
int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<pll,vector<pll>,greater<pll> >q;
q.push({0,1});
while(q.size())
{
auto t=q.top();
q.pop();
int ver=t.second,distance=t.first;
if(st[ver]) continue;
st[ver]=true;
for(int i=h[ver];~i;i=ne[i])
{
int j=e[i];
if(dist[j]>w[i]+distance)
{
dist[j]=w[i]+distance;
q.push({dist[j],j});
}
}
}
if(dist[n]>=0x3f3f3f3f) return -1;
return dist[n];
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
while (m -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
}
cout << dijkstra() << endl;
return 0;
}
spfa判负环
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int h[N],ne[N],w[N],e[N],idx;
void add(int a,int b,int c)
{
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
int n,m,dis[N],st[N],cnt[N];
bool spfa()
{
memset(dis,0x3f,sizeof dis);
queue<int>q;
for(int i=1;i<=n;i++)
{
q.push(i);
st[i]=1;
}
while(q.size())
{
int t=q.front();
q.pop();
st[t]=0;
for(int i=h[t];~i;i=ne[i])
{
int j=e[i];
if(dis[j]>dis[t]+w[i])
{
dis[j]=dis[t]+w[i];
cnt[j]=cnt[t]+1;
if(cnt[j]>=n) return true;
if(!st[j])
{
q.push(j);
st[j]=1;
}
}
}
}
return false;
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
if(spfa()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
克鲁斯卡尔 最小生成树
#include<bits/stdc++.h>
using namespace std;
const int N=2e6;
int n,m;
int f[N];
struct node{
int a,b,w;
bool operator<(const node &t)const{
return w<t.w;
}
}edges[N];
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,w;
cin>>a>>b>>w;
edges[i]={a,b,w};
}
int cnt=0,res=0;
sort(edges,edges+m);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=0;i<m;i++)
{
int a=edges[i].a,b=edges[i].b,w=edges[i].w;
a=find(a),b=find(b);
if(a!=b)
{
f[a]=b;
res+=w;
cnt++;
}
}
if(cnt<n-1) cout<<"impossible"<<endl;
else cout<<res<<endl;
return 0;
}
二分图最大匹配
#include <cstring>
#include <iostream>
using namespace std;
const int N = 510, M = 1e5 + 10;
int n1, n2, m;
int e[M], ne[M], h[N], idx;
bool st[N];
int match[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
bool find(int x)
{
for(int i=h[x];i!=-1;i=ne[i])
{
int j=e[i];
if(!st[j])
{
st[j]=1;
if(!match[j]||find(match[j]))
{
match[j]=x;
return true;
}
}
}
return 0;
}
int main()
{
scanf("%d%d%d", &n1, &n2, &m);
memset(h, -1, sizeof h);
while (m--)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
}
int res = 0;
for (int i = 1; i <= n1; i++) // 给每个新郎找女票。
{
memset(st, false, sizeof st); // 给每个新娘都盖上盖头。
if (find(i)) res++; // 如果找到一对,就成一对。看看最后最多能成多少对?
}
printf("%d\n", res);
}
posted on
浙公网安备 33010602011771号