1. 程式人生 > >【最短路】【二分圖匹配】【樹形背包DP】Day 10.8

【最短路】【二分圖匹配】【樹形背包DP】Day 10.8

void second eof 最小 span har mes find names

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 }

【最短路】【二分圖匹配】【樹形背包DP】Day 10.8