没有合适的资源?快使用搜索试试~ 我知道了~
首页ACM算法集锦(实现代码)
ACM算法集锦(实现代码)
需积分: 50 322 浏览量
更新于2023-03-16
评论 3
收藏 429KB DOC 举报
ACM算法集锦(实现代码),包括kurXX最小生成树、Prim、堆实现最短路、最短路DIJ普通版、floyd、拓扑排序、BELL_MAN、DFS强连通分支、最大匹配、最大权匹配,KM算法、两种欧拉路、求最小割集合的办法 【最小费用最大流】Edmonds Karp对偶算法、【题目1】N皇后问题(八皇后问题的扩展) 【题目2】排球队员站位问题 【题目3】把自然数N分解为若干个自然数之和。 【题目4】把自然数N分解为若干个自然数之积。 【题目5】马的遍历问题。 【题目6】加法分式分解 【题目7】地图着色问题 【题目8】在n*n的正方形中放置长为2,宽为1的长条块, 【题目9】找迷宫的最短路径。(广度优先搜索算法) 【题目10】火车调度问题 【题目11】农夫过河 【题目12】七段数码管问题。 【题目13】把1-8这8个数放入下图8个格中,要求相邻的格(横,竖,对角线)上填的数不连续. 【题目14】在4×4的棋盘上放置8个棋,要求每一行,每一列上只能放置2个. 【题目15】迷宫问题.求迷宫的路径.(深度优先搜索法) 【题目16】一笔画问题 【题目17】城市遍历问题. 【题目18】棋子移动问题 【题目19】求集合元素问题(1,2x+1,3X+1类)
资源详情
资源评论
资源推荐

1
ACM 算法资料集锦 2009 年 12 月 10 日星期四
kurXX 最小生成树
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
#define M 501
#define LIM 20000000
struct edg{
int u,v;
int w;
}all_e[M*M/2];
bool operator < (const edg &a,const edg &b){
return a.w<b.w;
}
int set[M];
inline bool uni(int set[],int a,int b){
int ac=0,a2=a,b2=b,bc=0;
while(set[a]!=0) {a=set[a];ac++;}
if(a2!=a) set[a2]=a;
while(set[b]!=0) {b=set[b];bc++;}
if(b2!=b) set[b2]=b;
if(a==b) return false;
if(ac<bc) set[a]=b;
else set[b]=a;
return true;
}
int main(){
int i,j,k,n,m,u,v,t;
cin >> t;
for(k=0;k<t;k++){
memset(set,0,sizeof(set));
cin >> n;
int ei=0;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(t!=0){
edg e;
e.u=i;e.v=j;
scanf("%d",&e.w);
if(i<j)
all_e[ei++]=e;
}
}
}
sort(&all_e[0],&all_e[ei]);
int count=0;
int size=ei;
int max=0;
for(i=0;i<size && count < n-1;i++){
if(uni(set,all_e[i].u,all_e[i].v)){
count++;
if(all_e[i].w>all_e[max].w) max=i;
}
}
printf("%d",all_e[max].w);
}
return 0;
}
Prim
#include <iostream>
using namespace std;
#define M 2001
int set[M]={0},g[M][M];
char str[M][8];
inline void make_map(int n,int g[M][M]){
int i,j,k;
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
int c=0;
for(k=0;k<7;k++)
if(str[i][k]!=str[j][k]) c++;
g[i][j]=g[j][i]=c;
}
}
}
int main(){
int n,q[M],qf=0,ql=0,d[M],u;
char c;
scanf("%d%c",&n,&c);
int i;
while(n!=0){
memset(set,0,sizeof(set)); memset(g,0,sizeof(g));
for(i=1;i<=n;i++) {
scanf("%s",&str[i]);
q[i-1]=i;
d[i]=2000000;
}
qf=0;ql=n-1;
make_map(n,g);

1
ACM 算法资料集锦 2009 年 12 月 10 日星期四
int sum=0;
int f=false;
while(qf<=ql){
int min=qf;
for(i=qf+1;i<=ql;i++){
if(d[q[i]] < d[q[min]]) min=i;
}
swap(q[qf],q[min]);
u=q[qf]; qf++;
if(f) sum+=d[u];
for(i=1;i<=n;i++){
if(g[u][i] !=0 && g[u][i] < d[i]) d[i]=g[u][i];
}
f=true;
}
printf("The highest possible quality is 1/%d.\n",sum);
scanf("%d%c",&n,&c);
}
return 0;
}
堆实现最短路
#include <iostream>
#include <string>
#include <stdlib.h>
#include <vector>;
using namespace std;
#define M 1001
#define LIM 2000000000
struct dd{ //最短距离
int w,q;//w 是距离值,q 是堆中的相对位置
}d[M],d2[M];
struct node{
int v,w;
};
int h[M],hs;
vector<node> g[M],g2[M];
void change_key(dd d[M],int v,int w){
d[v].w=w;
int i=d[v].q;
while(i>1 && d[h[i/2]].w>d[h[i]].w){
swap(h[i],h[i/2]);
swap(d[h[i]].q,d[h[i/2]].q);
i=i/2;
}
}
inline void min_heaphy(dd d[M],int *a,int i,int s){//s 为堆大小
int l=i*2,r=i*2+1;
int miner=i;
if (l<=s && d[a[i]].w>d[a[l]].w)
miner = l;
else miner=i;
if (r<=s && d[a[miner]].w>d[a[r]].w)
miner=r;
if(miner!=i){
swap(a[i],a[miner]);
swap(d[a[i]].q,d[a[miner]].q);
min_heaphy(d,a,miner,s);
}
}
inline void init(dd d[M],int n,int s){ //初始化图和堆
int i;
hs=n;
for(i=1;i<=n;i++){d[i].w=LIM;h[i]=d[i].q=i;}
change_key(d,s,0);
}
inline void relax(dd d[M],int u,int v,int duv){
if(d[v].w>d[u].w+duv) change_key(d,v,d[u].w+duv);
}
void dijkstra(vector<node> g[M],dd d[M],int n,int s){ //n is |V| && s is the
source
init(d,n,s);
int i;
while(hs!=0){
int u=h[1];
swap(h[1],h[hs]);
swap(d[h[1]].q,d[h[hs]].q);
hs--;
min_heaphy(d,h,1,hs);
for(i=0;i<g[u].size();i++) relax(d,u,g[u][i].v,g[u][i].w);
}
}
最短路 DIJ 普通版
#define M 101
#define LIM 20000000
int g[M][M],d[M],fd[2][M][M],gt[M][M],set[M];
inline void init(int d[M],int n,int s){ //初始化图
int i;
for(i=1;i<=n;i++) d[i]=LIM;

1
ACM 算法资料集锦 2009 年 12 月 10 日星期四
d[s]=0;
}
inline void relax(int d[M],int u,int v,int duv){
if(d[v]>d[u]+duv) d[v]=d[u]+duv;
}
void dijkstra(int g[M][M],int d[M],int n,int s){ //n is |V| && s is the source
init(d,n,s);
int q[M],ql=1,qf=1; //队列
int i;
for(i=1;i<=n;i++) q[ql++]=i;
while(qf!=ql){
int min=qf;
for(i=qf;i<ql;i++) if(d[q[i]]<d[q[min]]) min=i;
swap(q[qf],q[min]); //q[qf] is the min
int u=q[qf++];
for(i=1;i<=n;i++){
if(g[u][i]!=0) relax(d,u,i,g[u][i]);
}
}
}
floyd
#include <iostream>
#include <vector>
using namespace std;
#define M 301
#define LIM 200000000
int w[M][M],d[2][M][M];
void floyd(int g[M][M],int d[2][M][M],int n){
int i,j,k;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
d[0][i][j]=g[i][j];
}
d[0][i][i]=0;
} //这里是令 d[0]=g
for(k=1;k<=n;k++){
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
int t1=k%2; int t2=(t1+1)%2;
d[t1][i][j]=d[t2][i][j] < d[t2][i][k]+d[t2][k][j]?d[t2]
[i][j]:d[t2][i][k]+d[t2][k][j];
}
}
}
BELL_MAN
inline void init(int d[M],int n,int s){ //初始化图
int i;
for(i=1;i<=n;i++) d[i]=2000000000;
d[s]=0;
}
inline void relax(int d[M],int u,int v,int duv){
if(d[v]>d[u]+duv) d[v]=d[u]+duv;
}
void bell_man(int g[M][M],int d[M],int n,int s){ //n 个结点 s 为源点
int i,j,k;
init(d,n,s);
for(k=1;k<n;k++){
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
if(g[i][j]!=0) relax(d,i,j,g[i][j]);
}
}
}
拓扑排序
#include <iostream>
#include <stack>
#include <vector>
#include <list>
using namespace std;
vector <int> order;
void find_id(list<int> g[],int id[],int n){ //寻找入度,没有使用
int i;
list<int>::iterator k;
for(i=0;i<n;i++){
for(k=g[i].begin();k!=g[i].end();k++){
id[*k]++;
}
}
}
void topo(list<int> g[],int id[],int n,bool &OK,bool &incon){//OK==false
表示未确定顺序 incon==true 表示发现矛盾
stack<int> s;
order.erase(order.begin(),order.end());
int t[26];
copy(&id[0],&id[n],&t[0]);
int i;

1
ACM 算法资料集锦 2009 年 12 月 10 日星期四
for(i=0;i<n;i++){
if(id[i]==0)
s.push(i);
}
if(s.size()!=1) OK=false;
int count=0;
while(!s.empty()){
int v=s.top(); s.pop(); count++;
order.push_back(v);
list<int>::iterator k;
for(k=g[v].begin();k!=g[v].end();k++){
id[*k]--;
if(id[*k]==0) s.push(*k);
if(s.size()>1) OK=false;
}
}
if(order.size() < n) OK=false; //矛盾发生,会导致这种情况,小心
if(count < n) incon=true;
copy(&t[0],&t[n],&id[0]);
}
DFS 强连通分支
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define M 20005
vector<int> g[M],gt[M];
bool used[M];
int ft[M],sort_v[M],tim;
bool comp(const int &u,const int &v){
return ft[u]>ft[v];
}
inline int findp(int set[],int n){
int n2=n;
while(set[n]!=0) n=set[n];
if(n2!=n) set[n2]=n;
return n;
}
inline bool uni(int set[],int a,int b){
int ac=0,a2=a,b2=b,bc=0,t;
while(set[a]!=0) {a=set[a];ac++;}
while(a2!=a) {t=set[a2]; set[a2]=a; a2=t;};
while(set[b]!=0) {b=set[b];bc++;}
while(b2!=b) {t=set[b2]; set[b2]=b; b2=t;};
if(a==b) return false;
if(ac<bc) set[a]=b;
else set[b]=a;
return true;
}
void dfs(vector<int> g[M],int u){
if(used[u]) return;
tim++;
used[u]=true;
int i;
for(i=0;i<g[u].size();i++){
dfs(g,g[u][i]);
}
tim++;
ft[u]=tim;
return;
}
void dfs2(vector<int> g[],int u,int r,int set[]){
if(used[u]) return;
uni(set,u,r);
used[u]=true;
int i;
for(i=0;i<g[u].size();i++){
dfs2(g,g[u][i],u,set);
}
return;
}
void scc(int n,vector<int> g[M],int set[]){
int i,j;
tim=0;
memset(used,0,sizeof(used));
memset(set,0,sizeof(set));
for(i=1;i<=n;i++) sort_v[i]=i;
for(i=1;i<=n;i++) if(!used[i]) dfs(g,i); //compute finishing times
sort(&sort_v[1],&sort_v[n+1],comp); //decreasing f[u] order
memset(used,0,sizeof(used));
for(i=1;i<=n;i++) for(j=0;j<g[i].size();j++) gt[g[i]
[j]].push_back(i); //compute gt
for(i=1;i<=n;i++) if(!used[sort_v[i]])
dfs2(gt,sort_v[i],sort_v[i],set); //make the scc
}
int main(){
int i,j,n,m,u,v,set[M];
cin >> n >> m;
for(i=0;i<m;i++){
scanf("%d%d",&u,&v);

1
ACM 算法资料集锦 2009 年 12 月 10 日星期四
g[u].push_back(v);
}
scc(n,g,set);
int pi=1,ptosc[M];
struct Scc{
int p,n;
}sc[M];
memset(sc,0,sizeof(sc));
for(i=1;i<=n;i++){
int p=findp(set,i);
if(sc[p].p==0) {sc[p].p=pi; ptosc[pi++]=p;}
sc[p].n++;
}
int n2=pi-1,od[M];
memset(od,0,sizeof(od));
for(i=1;i<=n;i++){
for(j=0;j<g[i].size();j++){
u=findp(set,i); v=findp(set,g[i][j]);
if(sc[u].p!=sc[v].p) od[sc[u].p]++;
}
}
int sum=0,s1=0;
for(i=1;i<=n2;i++) if(od[i]==0) {s1++; sum+=sc[ptosc[i]].n;}
if(s1!=1) sum=0;
cout << sum << endl;
}
最大匹配
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
#define M 1001
int n,m,match[M],ans[M];
bool visit[M],g[M][M];
//O(n^3)
bool dfs(int k,bool map[M][M]){
int t;
for(int i = 1; i <= m; i++){
if(map[k][i] && !visit[i]){
visit[i] = true;
t = match[i];
match[i] = k;
if(t == 0 || dfs(t,map))
return true;
match[i] = t;
}
}
return false;
}
int main(){
int i,sum=0,t,j,u,v;
cin >> t;
while(t--){
sum=0;
memset(match,0,sizeof(match));
memset(g,0,sizeof(g));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d",&u,&v);
g[u][v]=true;
}
m=n;
for(i=1;i<=n; i++){
memset(visit,0,sizeof(visit));
if(dfs(i,g)) sum++;
}
cout << n-sum << endl;
}
return 0;
}
还有两个最大匹配模板
#include <iostream>
#include <string>
#include <math.h>
#include <vector>
using namespace std;
#define M 3001
bool g[M][M];
int mk[M] ,cx[M],pred[M],open[M],cy[M],nx,ny;
//边少适用 O(n^3)
int MaxMatchBFS()
{
int i , u , v , t , d , e , cur , tail , res(0) ;
memset(mk , 0xff , sizeof(mk)) ;
memset(cx , 0xff , sizeof(cx)) ;
memset(cy , 0xff , sizeof(cy)) ;
for (i = 0 ; i < nx ; i++){
pred[i] = -1 ;
for (open[cur = tail = 0] = i ; cur <= tail && cx[i] == -1 ; cur+
+){
剩余25页未读,继续阅读












安全验证
文档复制为VIP权益,开通VIP直接复制

评论0