再谈树
无根树转有根数
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100;
vector<int> G[maxn];
int n;
void read_tree(){
int u,v;
scanf("%d",&n);
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
}
int p[100];
void dfs(int u,int fa){//转化为u为根的子树,u的父结点为fa
int d=G[u].size();
for(int i=0;i<d;i++){
int v=G[u][i];
if(v!=fa) dfs(v,p[v]=u);
}
}
int main()
{
read_tree();
for(int i=0;i<n-1;i++){ printf("%d:",i);
for(int j=0;j<G[i].size();j++)
printf("%d ",G[i][j]);
printf("\n");
}
p[1]=-1;
dfs(1,-1);
for(int i=0;i<n;i++) printf("%d ",i); printf("\n");<pre name="code" class="cpp">const int maxn = 100;
int lch[maxn], rch[maxn]; char op[maxn]; //每个结点的左右子节点编号和字符
int nc=0; //结点数
int build_tree(char * s,int x,int y){
int i,c1=-1,c2=-1,p=0;
int u;
if(y-x==1) { //进一个字符建立单独结点
u = ++nc;
lch[u]=rch[u]=0; op[u]=s[x];
return u;
}
for(i=x;i<y;i++){
switch(s[i]){
case '(':p++;break;
case ')':p--;break;
case '+':case '-': if(!p) c1=i; break;
case '*':case '/': if(!p) c2=i; break;
}
}
if(c1<0) c1=c2;
if(c1<0) return build_tree(s,x+1,y-1);
u=++nc;
lch[u]=build_tree(s,x,c1);
ech[u]=build_tree(s,c1+1,y);
op[u]=s[c1];
return u;
}
for(int i=0;i<n;i++) printf("%d ",p[i]); printf("\n"); /* 初始的树 8 1 4 1 5 1 0 5 6 5 7 0 2 0 3 0:1 2 3 1:4 5 0 2:0 3:0 4:1 5:1 6 7 6:5 */ return 0;}
表达式树
const int maxn = 100;
int lch[maxn], rch[maxn]; char op[maxn]; //每个结点的左右子节点编号和字符
int nc=0; //结点数
int build_tree(char * s,int x,int y){
int i,c1=-1,c2=-1,p=0;
int u;
if(y-x==1) { //进一个字符建立单独结点
u = ++nc;
lch[u]=rch[u]=0; op[u]=s[x];
return u;
}
for(i=x;i<y;i++){
switch(s[i]){
case '(':p++;break;
case ')':p--;break;
case '+':case '-': if(!p) c1=i; break;
case '*':case '/': if(!p) c2=i; break;
}
}
if(c1<0) c1=c2;
if(c1<0) return build_tree(s,x+1,y-1);
u=++nc;
lch[u]=build_tree(s,x,c1);
ech[u]=build_tree(s,c1+1,y);
op[u]=s[c1];
return u;
}
例题11-1 公共表达式消除 uva12219
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 105;
struct Edge {
int u,v,cost;
bool operator < (const Edge& a) const {
return cost > a.cost;
}
};
int F[MAXN];int n,m;vector<Edge> edges;
int find(int x){
return x==F[x]?x:F[x]=find(F[x]);
}
int kruskal(int k){
for(int i=0;i<=n;i++) F[i]=i;
int cnt=0;
int minn=INF,maxn=0;
for(int i=k;i<m;i++)
{
Edge e = edges[i];
int v=e.v;
int u=e.u;
int fu=find(u);
int fv=find(v);
if(fu!=fv){
cnt++;
F[fu]=fv;
minn=min(e.cost,minn);
maxn =max(e.cost,maxn);
}
}
if(cnt!=n-1)return -1;
else return maxn-minn;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0) break;
edges.clear();
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
edges.push_back((Edge){a,b,c} );
}
sort(edges.begin(),edges.end());
int ans=INF;
for(int i=0;i<=m;i++){
int t=kruskal(i);
if(t==-1) break;
ans = min(ans,t);
}
if(ans == INF) printf("%d\n",-1);
else printf("%d\n",ans);
}
return 0;
}
例题11-3 买还是建 uva1151
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
struct point {
int x,y;
}pp[maxn];
struct edge
{
int s,e,dist;
}l[maxn*maxn];
int n,q,m;
int p[maxn];
vector<int> g[10];
int c[10];
int distance_(point a,point b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp(edge a,edge b){
return a.dist < b.dist;
}
int find_(int x){
return p[x]==x?x:p[x]=find_(p[x]);
}
bool merge_(int a,int b){
int x=find_(a);
int y=find_(b);
if(x==y) return false;
p[x]=y; return true;
}
int kruskal(){
int ans=0;
int num=0;
for(int i=0;i<m&&num<n-1;i++)
{
if(merge_(l[i].s,l[i].e))
{
num++;
ans += l[i].dist;
}
}
return ans;
}
void solve(){
for(int i=0;i<=n;i++) p[i]=i;
int ans=kruskal();
for(int s=1;s<(1<<q);s++){
int cost=0;
for(int tt=0;tt<=n;tt++) p[tt]=tt;
for(int j=0;j<q;j++){
if(!((s>>j)&1)) continue;
cost += c[j];
for(int k=0;k<g[j].size();k++)
{
merge_(g[j][k],g[j][0]);
}
}
ans =min(ans, cost+kruskal());
}
printf("%d\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
for(int i=0;i<10;i++) g[i].clear();
for(int i=0;i<q;i++){
int cnt;
scanf("%d%d",&cnt,&c[i]);
int a;
for(int j=0;j<cnt;j++){
scanf("%d",&a);
g[i].push_back(a);
}
}
for(int i=1;i<=n;i++){
scanf("%d%d",&pp[i].x,&pp[i].y);
}
m=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
l[m].s=i;
l[m].e=j;
l[m++].dist=distance_(pp[i],pp[j]);
}
}
sort(l,l+m,cmp);
solve();
if(t) printf("\n");
}
return 0;
}
Dijkstra算法: