最短路二分图匹配树形背包DPDay 10.8
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路二分图匹配树形背包DPDay 10.8相关的知识,希望对你有一定的参考价值。
T1
最短路
1 #include <cstdio> 2 #include <queue> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 typedef pair<int,int> P; 7 typedef pair<int,P> R; 8 priority_queue<R,vector<R>,greater<R> > que; 9 int m,n,a2,b2,a3,b3,ans=2000000000,sans[10001],a[101][101],cut[101][101],reg[101][101],b[101][101],pre[101][01],d[5]={1,0,-1,0,1},d2[4]={3,2,0,1}; 10 char ch,map[101][101]; 11 void bfsa()//老师 12 { 13 memset(reg,0,sizeof(reg)); 14 while(!que.empty()) 15 { 16 R x=que.top();que.pop(); 17 P y=x.second; 18 if (reg[y.first][y.second]) continue; 19 reg[y.first][y.second]=1; 20 for (int i=0;i<4;i++) 21 { 22 int a1=y.first+d[i],b1=y.second+d[i+1]; 23 if (a1<1||a1>m||b1<1||b1>n||map[a1][b1]==‘#‘) continue; 24 if (a[a1][b1]==-1||a[a1][b1]>a[y.first][y.second]+1) 25 { 26 a[a1][b1]=a[y.first][y.second]+1; 27 que.push(R(a[a1][b1],P(a1,b1))); 28 } 29 } 30 } 31 } 32 void bfsb()//学生 33 { 34 que.push(R(0,P(a2,b2))); 35 memset(reg,0,sizeof(reg)); 36 while(!que.empty()) 37 { 38 R x=que.top();que.pop(); 39 P y=x.second; 40 if (reg[y.first][y.second]) continue; 41 reg[y.first][y.second]=1; 42 for (int j=0;j<4;j++) 43 { 44 int i=d2[j]; 45 int a1=y.first+d[i],b1=y.second+d[i+1]; 46 if (a1<1||a1>m||b1<1||b1>n||map[a1][b1]==‘#‘) continue; 47 if ((b[y.first][y.second]+1)/4<a[a1][b1]&&(b[a1][b1]==-1||b[a1][b1]>b[y.first][y.second]+1)) 48 { 49 b[a1][b1]=b[y.first][y.second]+1; 50 que.push(R(b[a1][b1],P(a1,b1))); 51 } 52 } 53 } 54 } 55 void bfsc()//反向剪枝 56 { 57 que.push(R(ans,P(a3,b3))); 58 memset(reg,0,sizeof(reg)); 59 while(!que.empty()) 60 { 61 R x=que.top();que.pop(); 62 P y=x.second; 63 cut[y.first][y.second]=0; 64 if (reg[y.first][y.second]) continue; 65 reg[y.first][y.second]=1; 66 for (int j=0;j<4;j++) 67 { 68 int i=d2[j]; 69 int a1=y.first+d[i],b1=y.second+d[i+1]; 70 if (a1<1||a1>m||b1<1||b1>n||map[a1][b1]==‘#‘) continue; 71 if (b[a1][b1]==b[y.first][y.second]-1) 72 que.push(R(b[a1][b1],P(a1,b1))); 73 } 74 } 75 } 76 void dfs(int x,int y)//找字典序最小 77 { 78 int cnt=0; 79 while(x>=1&&x<=m&&y>=1&&y<=n) 80 { 81 if (cnt==ans) break; 82 for (int i=0;i<4;i++) 83 { 84 int j=d2[i]; 85 if (cut[x+d[j]][y+d[j+1]]==0&&b[x+d[j]][y+d[j+1]]==b[x][y]+1) 86 { 87 x=x+d[j];y=y+d[j+1]; 88 sans[cnt++]=i; 89 break; 90 } 91 } 92 } 93 } 94 int main() 95 { 96 freopen("Run.in","r",stdin); 97 freopen("Run.out","w",stdout); 98 memset(a,-1,sizeof(a)); 99 memset(b,-1,sizeof(b)); 100 memset(cut,-1,sizeof(cut)); 101 scanf("%d%d",&m,&n); 102 for (int i=1;i<=m;i++) 103 { 104 getchar(); 105 for (int j=1;j<=n;j++) 106 { 107 scanf("%c",&ch); 108 map[i][j]=ch; 109 if (ch==‘Z‘||ch==‘J‘||ch==‘T‘||ch==‘C‘) 110 {a[i][j]=0;que.push(R(0,P(i,j)));} 111 if (ch==‘P‘) a2=i,b2=j,b[i][j]=0; 112 } 113 } 114 bfsa(); 115 bfsb(); 116 for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) 117 if ((i==1||i==m||j==1||j==n)&&b[i][j]!=-1) {ans=b[i][j];a3=i,b3=j;} 118 if (ans==2000000000){printf("I am so sorry\n");return 0;} 119 printf("%d\n",ans+1); 120 bfsc(); 121 dfs(a2,b2); 122 sans[ans]=sans[ans-1]; 123 for (int i=0;i<=ans;i++) 124 { 125 if (sans[i]==0) printf("E"); 126 if (sans[i]==1) printf("N"); 127 if (sans[i]==2) printf("S"); 128 if (sans[i]==3) printf("W"); 129 } 130 }
T2
二分图匹配
1 #include <cstdio> 2 #include <cstring> 3 int x,y,m,f,in[1001],ans=0,girl[1001],line[1001][1001]; 4 bool find(int x) 5 { 6 for (int i=1;i<=f;i++) 7 { 8 if (line[x][i]==2&&!in[i]) 9 { 10 in[i]=1; 11 if (girl[i]==0||find(girl[i])) 12 { 13 girl[i]=x; 14 return 1; 15 } 16 } 17 } 18 return 0; 19 } 20 int main() 21 { 22 freopen("Seat.in","r",stdin); 23 freopen("Seat.out","w",stdout); 24 scanf("%d%d",&m,&f); 25 for (int i=1;i<=m;i++){ 26 scanf("%d",&x); 27 for (int j=1;j<=x;j++){ 28 scanf("%d",&y); 29 line[i][y]++; 30 } 31 } 32 for (int i=1;i<=f;i++){ 33 scanf("%d",&x); 34 for (int j=1;j<=x;j++){ 35 scanf("%d",&y); 36 line[y][i]++; 37 } 38 } 39 for (int i=1;i<=m;i++) 40 { 41 memset(in,0,sizeof(in)); 42 if (find(i)) ans++; 43 } 44 printf("%d",ans); 45 }
T3
树形背包DP
1 #include <cstdio> 2 #include <vector> 3 #include <iostream> 4 #include <map> 5 #include <vector> 6 using namespace std; 7 int m,n,p,x,y; 8 int a[101],b[101],nrt[101],f[101][1001]; 9 string s,s2; 10 map<string,int> mp; 11 vector<int> ve[101]; 12 void dfs(int x) 13 { 14 if (x!=0) for (int i=a[x];i<=p;i++) f[x][i]=b[x]; 15 for (int i=0;i<ve[x].size();i++)//分组 16 { 17 dfs(ve[x][i]); 18 for (int j=p;j>=a[x];j--)//当前背包的大小 19 { 20 for (int k=0;k<=j;k++)//每个组里的元素 21 { 22 if (j-k>=a[x]) f[x][j]=max(f[x][j],f[x][j-k]+f[ve[x][i]][k]); 23 } 24 } 25 } 26 } 27 int main() 28 { 29 freopen("Budget.in","r",stdin); 30 freopen("Budget.out","w",stdout); 31 cin>>m>>n>>p; 32 for (int i=1;i<=m;i++) 33 { 34 cin>>a[i]>>b[i]>>s; 35 mp[s]=i; 36 } 37 for (int i=1;i<=n;i++) 38 { 39 cin>>s>>s2; 40 nrt[mp[s2]]=1; 41 ve[mp[s]].push_back(mp[s2]); 42 } 43 for (int i=1;i<=m;i++) 44 if (!nrt[i]) ve[0].push_back(i); 45 dfs(0); 46 printf("%d",f[0][p]); 47 }
以上是关于最短路二分图匹配树形背包DPDay 10.8的主要内容,如果未能解决你的问题,请参考以下文章
二分图匹配入门专题1I - Hiding Gold light oj 1152二分图匹配-------------------我是终于不那么水的水题分割线------------------(代码片